home *** CD-ROM | disk | FTP | other *** search
/ Delphi 5 for Professionals / DELPHI5.iso / AddOns / Components / TEECHART / Src Code / TEENGINE.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1998-10-24  |  185.8 KB  |  6,243 lines

  1. {****************************************}
  2. {     TeeChart Pro Charting Library      }
  3. {  For Delphi 1,2,3,4 & C++ Builder 1&3  }
  4. { Copyright (c) 1995-98 by David Berneda }
  5. {         All Rights Reserved            }
  6. {****************************************}
  7. {$R-,Q-,S-,I-,A+,U-,X+,B-,W-,P-,V-,D+}
  8. {$I teedefs.inc}
  9. {$IFDEF D1}
  10. {$L-}
  11. {$ENDIF}
  12.  
  13. Unit TeEngine;
  14.  
  15. interface
  16.  
  17. uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  18.      Forms, ExtCtrls, TeeProcs, TeCanvas;
  19.  
  20. Const ChartMarkColor   = $80FFFF;  { default Series Mark back color }
  21.       {$IFDEF D1}
  22.       MinAxisIncrement = 0.00001;
  23.       MinAxisRange     = 0.001;
  24.       {$ELSE}
  25.       MinAxisIncrement = 0.000000000001;
  26.       MinAxisRange     = 0.0000000001;
  27.       {$ENDIF}
  28.  
  29.       TeeAllValues     = -1;
  30.  
  31.       ChartSamplesMax  = 1000;
  32.  
  33.       TeeDrawAxisBeforeSeries:Boolean=True;
  34.  
  35.       TeeAutoZOrder     = -1;
  36.       TeeNoPointClicked = -1;
  37.  
  38.       clTeeColor       = TColor(clScrollBar);
  39.       {$IFDEF D1}
  40.       clNone           = -2;
  41.       {$ENDIF}
  42.  
  43.       TeeCheckMarkArrowColor:Boolean=True;  { when False, Mark arrow pen
  44.                                               color is not altered }
  45.  
  46. Type
  47.   { Same like TBrush but with clTeeColor default instead of clWhite }
  48.   TChartBrush=class(TBrush)
  49.   public
  50.     Constructor Create(OnChangeEvent:TNotifyEvent);
  51.   published
  52.     property Color default clTeeColor;
  53.   end;
  54.  
  55.                                         { Example: }
  56.   TSeriesMarksStyle=( smsValue,             { 1234 }
  57.                       smsPercent,           { 12 % }
  58.                       smsLabel,             { Cars }
  59.                       smsLabelPercent,      { Cars 12 % }
  60.                       smsLabelValue,        { Cars 1234 }
  61.                       smsLegend,            { (Legend.Style) }
  62.                       smsPercentTotal,      { 12 % of 1234 }
  63.                       smsLabelPercentTotal, { Cars 12 % of 1234 }
  64.                       smsXValue);           { 21/6/1996 }
  65.  
  66.   PChartValue=^TChartValue;
  67.   TChartValue=Double;
  68.  
  69.   TChartListOrder=(loNone,loAscending,loDescending);
  70.  
  71.   TChartSeries=class;
  72.  
  73.   TChartValueList=class(TPersistent)
  74.   private
  75.     FDateTime    : Boolean;
  76.     FList        : TList;
  77.     FMaxValue    : Double;
  78.     FMinValue    : Double;
  79.     FMultiplier  : Double;
  80.     FName        : String;
  81.     FOrder       : TChartListOrder;
  82.     FOwner       : TChartSeries;
  83.     FTempValue   : Double;
  84.     FTotal       : Double;
  85.     FTotalABS    : Double;
  86.     FValueSource : String;
  87.     { internal }
  88.     Function GetMaxValue:Double;
  89.     Function GetMinValue:Double;
  90.     Function GetTotal:Double;
  91.     Function GetTotalABS:Double;
  92.     procedure SetDateTime(Value:Boolean);
  93.     Procedure SetMultiplier(Const Value:Double);
  94.     Procedure SetValueSource(Const Value:String);
  95.   protected
  96.     IDirtyStats  : Boolean;
  97.     Function GetValue(ValueIndex:Longint):Double; virtual;
  98.     Procedure SetValue(ValueIndex:Longint; Const AValue:Double); virtual;
  99.     Procedure ClearValues; virtual;
  100.     Procedure RecalcStats;
  101.     Function AddChartValue(Const Value:TChartValue):Longint; virtual;
  102.     Procedure InsertChartValue(ValueIndex:Longint; Const Value:TChartValue); virtual;
  103.   public
  104.     Constructor Create(AOwner:TChartSeries; Const AName:String); virtual;
  105.     Destructor Destroy; override;
  106.  
  107.     Procedure Assign(Source:TPersistent); override;
  108.     Function Count:Longint; virtual;
  109.     Procedure Delete(ValueIndex:Longint); virtual;
  110.     Procedure FillSequence;
  111.     Function First:Double;
  112.     Function Last:Double;
  113.     Function Locate(Const Value:Double):Longint;
  114.     Procedure Scroll; virtual;
  115.     Procedure Sort;
  116.  
  117.     property MaxValue:Double read GetMaxValue;
  118.     property MinValue:Double read GetMinValue;
  119.     property Owner:TChartSeries read FOwner;
  120.     property TempValue:Double read FTempValue write FTempValue;
  121.     property Total:Double read GetTotal;
  122.     property TotalABS:Double read GetTotalABS write FTotalABS; { <--write bcos Pie }
  123.     property Value[Index:Longint]:Double read GetValue write SetValue; default;
  124.   published
  125.     property DateTime:Boolean read FDateTime write SetDateTime;
  126.     property Name:String read FName write FName;
  127.     property Multiplier:Double read FMultiplier write SetMultiplier;
  128.     property Order:TChartListOrder read FOrder write FOrder;
  129.     property ValueSource:String read FValueSource write SetValueSource;
  130.   end;
  131.  
  132.   TCustomAxisPanel=class;
  133.  
  134.   TChartSeriesList=class(TList)
  135.   private
  136.     FOwner : TCustomAxisPanel;
  137.     procedure SetSeries(Index:Integer; Series:TChartSeries);
  138.     function GetSeries(Index:Integer):TChartSeries;
  139.   public
  140.     Function CountActive:Longint;
  141.     property Owner:TCustomAxisPanel read FOwner;
  142.     property Series[Index:Integer]:TChartSeries read GetSeries write SetSeries; {$IFNDEF D1} default; {$ENDIF}
  143.   end;
  144.  
  145.   TLegendTextStyle=( ltsPlain,ltsLeftValue,ltsRightValue,
  146.                      ltsLeftPercent,ltsRightPercent,ltsXValue);
  147.  
  148.   TAxisLabelStyle=(talAuto,talNone,talValue,talMark,talText);
  149.  
  150.   AxisException=class(Exception);
  151.  
  152.   TCustomChartAxis=class;
  153.  
  154.   TChartAxisTitle=class(TChartFontObject)
  155.   private
  156.     FAngle   : Integer;
  157.     FAxis    : TCustomChartAxis;
  158.     FCaption : String;
  159.     Function IsAngleStored:Boolean;
  160.     Procedure SetAngle(Value:Integer);
  161.     Procedure SetCaption(Const Value:String);
  162.   public
  163.     Procedure Assign(Source:TPersistent); override;
  164.   published
  165.     property Angle:Integer read FAngle write SetAngle stored IsAngleStored;
  166.     property Caption:String read FCaption write SetCaption;
  167.     property Font;
  168.   end;
  169.  
  170.   TCustomChartAxis=class(TPersistent)
  171.   private
  172.     { scales }
  173.     FAutomatic        : Boolean;
  174.     FAutomaticMaximum : Boolean;
  175.     FAutomaticMinimum : Boolean;
  176.     FDesiredIncrement : Double;
  177.     FMaximumValue     : Double;
  178.     FMinimumValue     : Double;
  179.     FLogarithmic      : Boolean;
  180.     FLogarithmicBase  : Integer;
  181.  
  182.     { axis }
  183.     FAxis             : TChartAxisPen;
  184.     FPosAxis          : Integer;
  185.  
  186.     { title }
  187.     FAxisTitle        : TChartAxisTitle;
  188.     FTitleSize        : Integer;
  189.     FPosTitle         : Integer;
  190.  
  191.     { grid }
  192.     FGrid             : TDottedGrayPen;
  193.     FGridCentered     : Boolean;
  194.  
  195.     { labels }
  196.     FLabels           : Boolean;
  197.     FLabelsAngle      : Integer;
  198.     FLabelsFont       : TFont;
  199.     FLabelsOnAxis     : Boolean;
  200.     FLabelsSeparation : Integer;
  201.     FLabelsSize       : Integer;
  202.     FLabelStyle       : TAxisLabelStyle;
  203.     FPosLabels        : Integer;
  204.     FAxisValuesFormat : String;
  205.     FDateTimeFormat   : String;
  206.     FExactDateTime    : Boolean;
  207.     FRoundFirstLabel  : Boolean;
  208.     FLabelsMultiLine  : Boolean;
  209.  
  210.     { ticks }
  211.     FMinorTickCount   : Integer;
  212.     FMinorTickLength  : Integer;
  213.     FMinorTicks       : TDarkGrayPen;
  214.     FTicks            : TDarkGrayPen;
  215.     FTicksInner       : TDarkGrayPen;
  216.     FTickInnerLength  : Integer;
  217.     FTickLength       : Integer;
  218.     FTickOnLabelsOnly : Boolean;
  219.  
  220.     { other }
  221.     FInverted         : Boolean;
  222.     FHorizontal       : Boolean;
  223.     FOtherSide        : Boolean;
  224.     FParentChart      : TCustomAxisPanel;
  225.     FVisible          : Boolean;
  226.     FStartPosition    : Double;
  227.     FEndPosition      : Double;
  228.     FPositionPercent  : Double;
  229.  
  230.     { internal }
  231.     IMaximum          : Double;
  232.     IMinimum          : Double;
  233.     IRange            : Double;
  234.     IAxisDateTime     : Boolean;
  235.     ICenterPos        : Integer;
  236.     IDefaultTitleAngle: Integer;
  237.     Function CalcDateTimeIncrement(MaxNumLabels:Longint):Double;
  238.     Function CalcLabelsIncrement(MaxNumLabels:Longint):Double;
  239.     Function GetRectangleEdge(Const R:TRect):Integer;
  240.     Function ApplyPosition(APos:Integer; Const R:TRect):Integer;
  241.     Function InternalCalcLabelsIncrement(MaxNumLabels:Longint):Double;
  242.     function IsAxisValuesFormatStored:Boolean;
  243.     Function IsMaxStored:Boolean;
  244.     Function IsMinStored:Boolean;
  245.     Procedure SetAutomatic(Value:Boolean);
  246.     Procedure SetAutomaticMinimum(Value:Boolean);
  247.     Procedure SetAutomaticMaximum(Value:Boolean);
  248.     Procedure SetAxis(Value:TChartAxisPen);
  249.     procedure SetAxisTitle(Value:TChartAxisTitle);
  250.     Procedure SetDateTimeFormat(Const Value:String);
  251.     Procedure SetDesiredIncrement(Const Value:Double);
  252.     Procedure SetExactDateTime(Value:Boolean);
  253.     Procedure SetGrid(Value:TDottedGrayPen);
  254.     procedure SetGridCentered(Value:Boolean);
  255.     Procedure SetInverted(Value:Boolean);
  256.     Procedure SetLabels(Value:Boolean);
  257.     Procedure SetLabelsFont(Value:TFont);
  258.     Function IsFontStored:Boolean;
  259.     Procedure SetLabelStyle(Value:TAxisLabelStyle);
  260.     Procedure SetLabelsOnAxis(Value:Boolean);
  261.     Procedure SetLabelsAngle(Value:Integer);
  262.     Procedure SetLabelsMultiLine(Value:Boolean);
  263.     Procedure SetLabelsSeparation(Value:Integer);
  264.     Procedure SetLabelsSize(Value:Integer);
  265.     Procedure SetLogarithmic(Value:Boolean);
  266.     Procedure SetLogarithmicBase(Value:Integer);
  267.     Procedure SetMaximum(Const Value:Double);
  268.     Procedure SetMinimum(Const Value:Double);
  269.     Procedure SetMinorTickCount(Value:Integer);
  270.     Procedure SetMinorTickLength(Value:Integer);
  271.     Procedure SetMinorTicks(Value:TDarkGrayPen);
  272.     procedure SetStartPosition(Const Value:Double);
  273.     procedure SetEndPosition(Const Value:Double);
  274.     procedure SetPositionPercent(Const Value:Double);
  275.     procedure SetRoundFirstLabel(Value:Boolean);
  276.     Procedure SetTickLength(Value:Integer);
  277.     Procedure SetTickInnerLength(Value:Integer);
  278.     Procedure SetTicks(Value:TDarkGrayPen);
  279.     Procedure SetTicksInner(Value:TDarkGrayPen);
  280.     procedure SetTickOnLabelsOnly(Value:Boolean);
  281.     Procedure SetTitleSize(Value:Integer);
  282.     Procedure SetValuesFormat(Const Value:String);
  283.     Procedure SetVisible(Value:Boolean);
  284.  
  285.     Function InternalCalcLogPosValue(IsX:Boolean; Const Value:Double):Longint;
  286.     Function InternalCalcDepthPosValue(Const Value:Double):Longint;
  287.     Function InternalCalcLog(Var LogMax,LogMin:Double):Double;
  288.     Function InternalCalcPosValue(Const Value:Double; FromEnd:Boolean):Longint;
  289.     {$IFNDEF D1}
  290.     Function IsPosStored:Boolean;
  291.     Function IsStartStored:Boolean;
  292.     Function IsEndStored:Boolean;
  293.     {$ENDIF}
  294.   protected
  295.     Procedure DrawAxisLine(AWallSize:Integer); virtual; abstract;
  296.   public
  297.     IStartPos         : Integer;
  298.     IEndPos           : Integer;
  299.     IAxisSize         : Integer;
  300.     IsDepthAxis       : Boolean;
  301.     Procedure InternalCalcPositions;
  302.     Function InternalCalcSize( tmpFont:TFont;
  303.                                tmpAngle:Longint;
  304.                                Const tmpText:String;
  305.                                tmpSize:Longint):Longint;
  306.     Procedure InternalSetInverted(Value:Boolean);
  307.     Procedure CalcRect(Var R:TRect; InflateChartRectangle:Boolean);
  308.     Procedure InternalSetMaximum(Const Value:Double);
  309.     Procedure InternalSetMinimum(Const Value:Double);
  310.     Function SizeTickAxis:Integer;
  311.     Function SizeTitle:Integer;
  312.     Function SizeLabels:Integer;
  313.     Procedure RecalcSizeCenter;
  314.  
  315.     Constructor Create(AOwner: TCustomAxisPanel);
  316.     Destructor Destroy; override;
  317.  
  318.     Function MaxLabelsWidth:Longint;
  319.     Function LabelWidth(Const Value:Double):Longint;
  320.     Function LabelHeight(Const Value:Double):Longint;
  321.     Function LabelValue(Const Value:Double):String;
  322.     Function CalcLabelStyle:TAxisLabelStyle;
  323.     Procedure DrawTitle(x,y:Longint);
  324.     procedure DrawAxisLabel(x,y,Angle:Integer; Const St:String);
  325.  
  326.     Function CalcPosValue(Const Value:Double):Longint;
  327.     Function CalcXPosValue(Const Value:Double):Longint;
  328.     Function CalcYPosValue(Const Value:Double):Longint;
  329.  
  330.     Function CalcSizeValue(Const Value:Double):Longint;
  331.  
  332.     Function CalcPosPoint(Value:Longint):Double;
  333.  
  334.     Procedure CustomDrawMinMax( APosLabels,
  335.                                 APosTitle,
  336.                                 APosAxis:Integer;
  337.                                 GridVisible:Boolean;
  338.                                 Const AMinimum,AMaximum,AIncrement:Double);
  339.     Procedure CustomDraw( APosLabels,APosTitle,APosAxis:Integer;
  340.                           GridVisible:Boolean);
  341.     Procedure CustomDrawStartEnd( APosLabels,APosTitle,APosAxis:Integer;
  342.                                   GridVisible:Boolean; AStartPos,AEndPos:Integer);
  343.     Procedure CustomDrawMinMaxStartEnd( APosLabels,
  344.                                         APosTitle,
  345.                                         APosAxis:Integer;
  346.                                         GridVisible:Boolean;
  347.                                         Const AMinimum,AMaximum,AIncrement:Double;
  348.                                         AStartPos,AEndPos:Integer);
  349.  
  350.     Procedure Draw(CalcPosAxis:Boolean);
  351.     procedure Assign(Source: TPersistent); override;
  352.     Procedure AdjustMaxMin;
  353.     Procedure CalcMinMax(Var AMin,AMax:Double);
  354.     Procedure Scroll(Const Offset:Double; CheckLimits:Boolean);
  355.     Function Clicked(x,y:Integer):Boolean;
  356.     Function IsDateTime:Boolean;
  357.     Procedure SetMinMax(Const AMin,AMax:Double);
  358.     Function CalcXYIncrement(MaxLabelSize:Integer):Double;
  359.     Function CalcIncrement:Double;
  360.     Procedure AdjustMaxMinRect(Const Rect:TRect);
  361.     Procedure IncDecDateTime( Increment:Boolean;
  362.                               Var Value:Double;
  363.                               Const AnIncrement:Double;
  364.                               tmpWhichDateTime:TDateTimeStep );
  365.  
  366.    { public }
  367.     property Horizontal : Boolean read FHorizontal write FHorizontal;
  368.     property OtherSide  : Boolean read FOtherSide write FOtherSide;
  369.     property PosAxis    : Integer read FPosAxis;
  370.     property PosLabels  : Integer read FPosLabels;
  371.     property PosTitle   : Integer read FPosTitle;
  372.     property ParentChart: TCustomAxisPanel read FParentChart;
  373.  
  374.     { to be published }
  375.     property Automatic:Boolean read FAutomatic write SetAutomatic default True;
  376.     property AutomaticMaximum:Boolean read FAutomaticMaximum write SetAutomaticMaximum default True;
  377.     property AutomaticMinimum:Boolean read FAutomaticMinimum write SetAutomaticMinimum default True;
  378.     property Axis:TChartAxisPen read FAxis write SetAxis;
  379.     property AxisValuesFormat:String read FAxisValuesFormat
  380.                                      write SetValuesFormat stored IsAxisValuesFormatStored;
  381.     property DateTimeFormat:String read FDateTimeFormat write SetDateTimeFormat;
  382.     property ExactDateTime:Boolean read FExactDateTime write SetExactDateTime default True;
  383.     property Grid:TDottedGrayPen read FGrid write SetGrid;
  384.     property GridCentered:Boolean read FGridCentered write SetGridCentered default False;
  385.     property Increment:Double read FDesiredIncrement write SetDesiredIncrement;
  386.     property Inverted:Boolean read FInverted write SetInverted default False;
  387.  
  388.     property Labels:Boolean read FLabels write SetLabels default True;
  389.     property LabelsAngle:Integer read FLabelsAngle write SetLabelsAngle default 0;
  390.     property LabelsFont:TFont read FLabelsFont write SetLabelsFont stored IsFontStored;
  391.     property LabelsMultiLine:Boolean read FLabelsMultiLine write SetLabelsMultiLine default False;
  392.     property LabelsOnAxis:Boolean read FLabelsOnAxis write SetLabelsOnAxis default True;
  393.     property LabelsSeparation:Integer read FLabelsSeparation
  394.                                       write SetLabelsSeparation default 10;
  395.     property LabelsSize:Integer read FLabelsSize write SetLabelsSize default 0;
  396.     property LabelStyle:TAxisLabelStyle read FLabelStyle write SetLabelStyle default talAuto;
  397.  
  398.     property Logarithmic:Boolean read FLogarithmic write SetLogarithmic default False;
  399.     property LogarithmicBase:Integer read FLogarithmicBase write SetLogarithmicBase default 10;
  400.     property Maximum:Double read FMaximumValue write SetMaximum stored IsMaxStored;
  401.     property Minimum:Double read FMinimumValue write SetMinimum stored IsMinStored;
  402.     property MinorTickCount:Integer read FMinorTickCount write SetMinorTickCount default 3;
  403.     property MinorTickLength:Integer read FMinorTickLength write SetMinorTickLength default 2;
  404.     property MinorTicks:TDarkGrayPen read FMinorTicks write SetMinorTicks;
  405.     property StartPosition:Double read FStartPosition write SetStartPosition
  406.                                     {$IFNDEF D1}stored IsStartStored{$ENDIF};
  407.     property EndPosition:Double read FEndPosition write SetEndPosition
  408.                                     {$IFNDEF D1}stored IsEndStored{$ENDIF};
  409.     property PositionPercent:Double read FPositionPercent write SetPositionPercent
  410.                                     {$IFNDEF D1}stored IsPosStored{$ENDIF};
  411.     property RoundFirstLabel:Boolean read FRoundFirstLabel write SetRoundFirstLabel default True;
  412.     property TickInnerLength:Integer read FTickInnerLength write SetTickInnerLength default 0;
  413.     property TickLength:Integer read FTickLength write SetTickLength default 4;
  414.     property Ticks:TDarkGrayPen read FTicks write SetTicks;
  415.     property TicksInner:TDarkGrayPen read FTicksInner write SetTicksInner;
  416.     property TickOnLabelsOnly:Boolean read FTickOnLabelsOnly write SetTickOnLabelsOnly default True;
  417.     property Title:TChartAxisTitle read FAxisTitle write SetAxisTitle;
  418.     property TitleSize:Integer read FTitleSize write SetTitleSize default 0;
  419.     property Visible:Boolean read FVisible write SetVisible default True;
  420.   end;
  421.  
  422.   TChartAxis=class(TCustomChartAxis)
  423.   protected
  424.     Procedure DrawAxisLine(AWallSize:Integer); override;
  425.   published
  426.     property Automatic;
  427.     property AutomaticMaximum;
  428.     property AutomaticMinimum;
  429.     property Axis;
  430.     property AxisValuesFormat;
  431.     property DateTimeFormat;
  432.     property ExactDateTime;
  433.     property Grid;
  434.     property GridCentered;
  435.     property Increment;
  436.     property Inverted;
  437.     property Labels;
  438.     property LabelsAngle;
  439.     property LabelsFont;
  440.     property LabelsMultiLine;
  441.     property LabelsOnAxis;
  442.     property LabelsSeparation;
  443.     property LabelsSize;
  444.     property LabelStyle;
  445.     property Logarithmic;
  446.     property LogarithmicBase;
  447.     property Maximum;
  448.     property Minimum;
  449.     property MinorTickCount;
  450.     property MinorTickLength;
  451.     property MinorTicks;
  452.     property StartPosition;
  453.     property EndPosition;
  454.     property PositionPercent;
  455.     property RoundFirstLabel;
  456.     property TickInnerLength;
  457.     property TickLength;
  458.     property TickOnLabelsOnly;
  459.     property Ticks;
  460.     property TicksInner;
  461.     property Title;
  462.     property TitleSize;
  463.     property Visible;
  464.   end;
  465.  
  466.   TChartDepthAxis=class(TCustomChartAxis)
  467.   protected
  468.     Procedure DrawAxisLine(AWallSize:Integer); override;
  469.   published
  470.     property Automatic;
  471.     property AutomaticMaximum;
  472.     property AutomaticMinimum;
  473.     property Axis;
  474.     property AxisValuesFormat;
  475.     property DateTimeFormat;
  476.     property ExactDateTime;
  477.     property Grid;
  478.     property Increment;
  479.     property Inverted;
  480.     property Labels;
  481.     property LabelsAngle;
  482.     property LabelsFont;
  483.     property LabelsMultiLine;
  484.     property LabelsOnAxis;
  485.     property LabelsSeparation;
  486.     property LabelsSize;
  487.     property LabelStyle;
  488.     property Logarithmic;
  489.     property LogarithmicBase;
  490.     property Maximum;
  491.     property Minimum;
  492.     property MinorTickCount;
  493.     property MinorTickLength;
  494.     property MinorTicks;
  495.     property RoundFirstLabel;
  496.     property TickInnerLength;
  497.     property TickLength;
  498.     property TickOnLabelsOnly;
  499.     property Ticks;
  500.     property TicksInner;
  501.     property Title;
  502.     property TitleSize;
  503.     property Visible default False;
  504.   end;
  505.  
  506.   TSeriesMouseMove=procedure( Sender:TChartSeries;
  507.                               Shift: TShiftState;
  508.                               X, Y: Integer) of object;
  509.  
  510.   TSeriesClick=procedure( Sender:TChartSeries;
  511.                           ValueIndex:Integer;
  512.                           Button:TMouseButton;
  513.                           Shift: TShiftState;
  514.                           X, Y: Integer) of object;
  515.  
  516.   TSeriesDblClick=procedure( Sender:TChartSeries;
  517.                              ValueIndex:Longint) of object;
  518.  
  519.   TAxisOnGetLabel=Procedure( Sender:TChartAxis; Series:TChartSeries;
  520.                              ValueIndex:Longint; Var LabelText:String) of object;
  521.  
  522.   TAxisOnGetNextLabel=Procedure( Sender:TChartAxis; LabelIndex:Longint;
  523.                                  Var LabelValue:Double; Var Stop:Boolean) of object;
  524.  
  525.   TValueEvent=(veClear,veAdd,veDelete,veRefresh,veModify);
  526.  
  527.   THorizAxis = (aTopAxis,aBottomAxis,aBothHorizAxis,aCustomHorizAxis);
  528.   TVertAxis  = (aLeftAxis,aRightAxis,aBothVertAxis,aCustomVertAxis);
  529.  
  530.   TChartClickedPartStyle=( cpNone,
  531.                            cpLegend,
  532.                            cpAxis,
  533.                            cpSeries,
  534.                            cpTitle,
  535.                            cpFoot,
  536.                            cpChartRect );
  537.  
  538.   TChartClickedPart=Record
  539.     Part       : TChartClickedPartStyle;
  540.     PointIndex : Longint;
  541.     ASeries    : TChartSeries;
  542.     AAxis      : TCustomChartAxis;
  543.   end;
  544.  
  545.   TCustomAxisPanel=class(TCustomTeePanelExtended)
  546.   private
  547.     { Private declarations }
  548.     FSeriesList       : TChartSeriesList;
  549.     FDepthAxis        : TChartDepthAxis;
  550.     FTopAxis          : TChartAxis;
  551.     FBottomAxis       : TChartAxis;
  552.     FLeftAxis         : TChartAxis;
  553.     FRightAxis        : TChartAxis;
  554.  
  555.     FView3DWalls      : Boolean;
  556.     FClipPoints       : Boolean;
  557.     FAxisVisible      : Boolean;
  558.     FOnGetAxisLabel   : TAxisOnGetLabel;
  559.     FOnGetNextAxisLabel:TAxisOnGetNextLabel;
  560.  
  561.     FOnPageChange     : TNotifyEvent;
  562.     FOnBeforeDrawAxes : TNotifyEvent;
  563.     FOnBeforeDrawSeries:TNotifyEvent;
  564.  
  565.     FPage             : Longint;
  566.     FMaxPointsPerPage : Longint;
  567.     FScaleLastPage    : Boolean;
  568.  
  569.     FMaxZOrder        : Integer;
  570.     FSeriesWidth3D    : Integer;
  571.     FSeriesHeight3D   : Integer;
  572.  
  573.     Procedure CheckOtherSeries(Dest,Source:TChartSeries);
  574.     Function GetSeries(Index:Longint):TChartSeries;
  575.     Procedure InternalAddSeries(ASeries:TChartSeries);
  576.     Function InternalMinMax(AAxis:TCustomChartAxis; IsMin,IsX:Boolean):Double;
  577.     Procedure SetAxisVisible(Value:Boolean);
  578.     Procedure SetBottomAxis(Value:TChartAxis);
  579.     procedure SetClipPoints(Value:Boolean);
  580.     Procedure SetDepthAxis(Value:TChartDepthAxis);
  581.     Procedure SetLeftAxis(Value:TChartAxis);
  582.     Procedure SetMaxPointsPerPage(Value:Longint);
  583.     Procedure SetRightAxis(Value:TChartAxis);
  584.     Procedure SetScaleLastPage(Value:Boolean);
  585.     Procedure SetTopAxis(Value:TChartAxis);
  586.     procedure SetView3DWalls(Value:Boolean);
  587.   protected
  588.     FAxes : TList;
  589.     { Protected declarations }
  590.     Procedure CalcAxisRect; virtual; abstract;
  591.     Procedure CalcSeriesRect; virtual; abstract;
  592.     Function CalcWallSize(Axis:TCustomChartAxis):Longint; virtual; abstract;
  593.     procedure DrawTitlesAndLegend; virtual; abstract;
  594.     Procedure DrawWalls; virtual; abstract;
  595.     Function IsAxisVisible(Axis:TCustomChartAxis):Boolean;
  596.     procedure RemovedDataSource( ASeries: TChartSeries;
  597.                                  AComponent: TComponent ); dynamic;
  598.     Procedure SetPage(Value:Longint); virtual;
  599.     {$IFDEF D1}
  600.     Procedure WriteComponents(Writer:TWriter); override;
  601.     {$ELSE}
  602.     Procedure GetChildren(Proc:TGetChildProc{$IFDEF D3}; Root:TComponent{$ENDIF}); override;
  603.     {$ENDIF}
  604.   public
  605.     { Public declarations }
  606.     LegendColor   : TColor;
  607.  
  608.     Constructor Create(AOwner: TComponent); override;
  609.     Destructor Destroy; override;
  610.  
  611.     { public methods }
  612.     procedure Assign(Source:TPersistent); override;
  613.     Function ActiveSeriesLegend(ItemIndex:Longint):TChartSeries;
  614.     Procedure AddSeries(ASeries:TChartSeries);
  615.     Procedure CalcSize3DWalls;
  616.     Procedure CheckDatasource(ASeries:TChartSeries); virtual;
  617.     Function FormattedValueLegend(ASeries:TChartSeries; ValueIndex:Longint):String; virtual;
  618.     Procedure FreeAllSeries;
  619.     Function GetAxisSeries(Axis:TCustomChartAxis):TChartSeries;
  620.     Function GetFreeSeriesColor(CheckBackground:Boolean):TColor;
  621.     Function GetMaxValuesCount:Longint;
  622.     Procedure InternalDraw(Const UserRectangle:TRect); override;
  623.     Function IsFreeSeriesColor(AColor:TColor; CheckBackground:Boolean):Boolean; virtual; abstract;
  624.     Function IsValidDataSource(ASeries:TChartSeries; AComponent:TComponent):Boolean; virtual;
  625.     Function MaxXValue(AAxis:TChartAxis):Double;
  626.     Function MaxYValue(AAxis:TChartAxis):Double;
  627.     Function MinXValue(AAxis:TChartAxis):Double;
  628.     Function MinYValue(AAxis:TChartAxis):Double;
  629.     Function MaxMarkWidth:Longint;
  630.     Function MaxTextWidth:Longint;
  631.     Function NumPages:Longint; dynamic;
  632.     Procedure RemoveSeries(ASeries:TChartSeries);
  633.     property Series[Index:Longint]:TChartSeries read GetSeries; default;
  634.     Function SeriesCount:Longint;
  635.     Function SeriesTitleLegend(SeriesIndex:Longint):String;
  636.  
  637.     { public properties }
  638.     property AxesList:TList read FAxes;
  639.     property MaxZOrder:Integer read FMaxZOrder write FMaxZOrder;
  640.     property SeriesWidth3D:Integer read FSeriesWidth3D;
  641.     property SeriesHeight3D:Integer read FSeriesHeight3D;
  642.  
  643.     { to be published properties }
  644.     property AxisVisible:Boolean read FAxisVisible write SetAxisVisible default True;
  645.     property BottomAxis:TChartAxis read FBottomAxis write SetBottomAxis;
  646.     property ClipPoints:Boolean read FClipPoints write SetClipPoints default True;
  647.     property Color;
  648.     property DepthAxis:TChartDepthAxis read FDepthAxis write SetDepthAxis;
  649.     property LeftAxis:TChartAxis read FLeftAxis write SetLeftAxis;
  650.     property MaxPointsPerPage:Longint read FMaxPointsPerPage write SetMaxPointsPerPage default 0;
  651.     property Page:Longint read FPage write SetPage default 1;
  652.     property RightAxis:TChartAxis read FRightAxis write SetRightAxis;
  653.     property ScaleLastPage:Boolean read FScaleLastPage write SetScaleLastPage default True;
  654.     property SeriesList:TChartSeriesList read FSeriesList;
  655.     property TopAxis:TChartAxis read FTopAxis write SetTopAxis;
  656.     property View3DWalls:Boolean read FView3DWalls write SetView3DWalls default True;
  657.  
  658.     { to be published events }
  659.     property OnBeforeDrawAxes:TNotifyEvent read FOnBeforeDrawAxes write FOnBeforeDrawAxes;
  660.     property OnBeforeDrawSeries:TNotifyEvent read FOnBeforeDrawSeries write FOnBeforeDrawSeries;
  661.     property OnGetAxisLabel:TAxisOnGetLabel read FOnGetAxisLabel write FOnGetAxisLabel;
  662.     property OnGetNextAxisLabel:TAxisOnGetNextLabel read FOnGetNextAxisLabel
  663.                                                     write FOnGetNextAxisLabel;
  664.     property OnPageChange:TNotifyEvent read FOnPageChange write FOnPageChange;
  665.   end;
  666.  
  667.   TSeriesMarkPosition=class
  668.   public
  669.     ArrowFrom   : TPoint;
  670.     ArrowTo     : TPoint;
  671.     Custom      : Boolean;
  672.     Height      : Integer;
  673.     LeftTop     : TPoint;
  674.     Width       : Integer;
  675.     Procedure Assign(Source:TSeriesMarkPosition);
  676.     Function Bounds:TRect;
  677.   end;
  678.  
  679.   TSeriesMarksPositions=class(TList)
  680.   private
  681.     Procedure SetPosition(Index:Integer; APosition:TSeriesMarkPosition);
  682.     Function GetPosition(Index:Integer):TSeriesMarkPosition;
  683.   public
  684.     Procedure Automatic(Index:Integer);
  685.     property Position[Index:Integer]:TSeriesMarkPosition read GetPosition
  686.                                     write SetPosition;{$IFNDEF D1}default;{$ENDIF}
  687.   end;
  688.  
  689.   TSeriesMarks=class(TPersistent)
  690.   private
  691.     FArrow           : TChartArrowPen;
  692.     FArrowLength     : Integer;
  693.     FBackColor       : TColor;
  694.     FBackTransparent : Boolean;
  695.     FClip            : Boolean;
  696.     FFrame           : TChartPen;
  697.     FFont            : TFont;
  698.     FMarkerStyle     : TSeriesMarksStyle;
  699.     FParent          : TChartSeries;
  700.     FPositions       : TSeriesMarksPositions;
  701.     FVisible         : Boolean;
  702.     FZPosition       : Integer;
  703.     Procedure SetStyle(Value:TSeriesMarksStyle);
  704.     Procedure SetFont(Value:TFont);
  705.     Procedure SetClip(Value:Boolean);
  706.     Procedure SetFrame(Value:TChartPen);
  707.     Procedure SetArrow(Value:TChartArrowPen);
  708.     Procedure SetArrowLength(Value:Integer);
  709.     Function IsFontStored:Boolean;
  710.     Procedure SetVisible(Value:Boolean);
  711.     Procedure SetBackColor(Value:TColor);
  712.     Procedure SetBackTransparent(Value:Boolean);
  713.   protected
  714.     Procedure ClearPositions;
  715.     Procedure UsePosition(Index:Integer; Var MarkPosition:TSeriesMarkPosition);
  716.   public
  717.     Constructor Create(AOwner:TChartSeries);
  718.     Destructor Destroy; override;
  719.  
  720.     Procedure Assign(Source:TPersistent); override;
  721.     Function Clicked(X,Y:Integer):Integer;
  722.     Procedure Draw(Index:Integer; AColor:TColor; Const St:String; APosition:TSeriesMarkPosition);
  723.     property ParentSeries:TChartSeries read FParent;
  724.     property Positions:TSeriesMarksPositions read FPositions;
  725.     property ZPosition : Integer read FZPosition write FZPosition;
  726.   published
  727.     property Arrow:TChartArrowPen read FArrow write SetArrow;
  728.     property ArrowLength:Integer read FArrowLength write SetArrowLength;
  729.     property BackColor:TColor read FBackColor write SetBackColor default ChartMarkColor;
  730.     property Clip:Boolean read FClip write SetClip default False;
  731.     property Font:TFont read FFont write SetFont stored IsFontStored;
  732.     property Frame:TChartPen read FFrame write SetFrame;
  733.     property Style:TSeriesMarksStyle read FMarkerStyle
  734.                                      write SetStyle default smsLabel;
  735.     property Transparent:Boolean read FBackTransparent write SetBackTransparent default False;
  736.     property Visible:Boolean read FVisible write SetVisible;
  737.   end;
  738.  
  739.   TSeriesOnBeforeAdd=Function(Sender:TChartSeries):Boolean of object;
  740.   TSeriesOnAfterAdd=Procedure(Sender:TChartSeries; ValueIndex:Longint) of object;
  741.   TSeriesOnClear=Procedure(Sender:TChartSeries) of object;
  742.   TSeriesOnGetMarkText=Procedure(Sender:TChartSeries; ValueIndex:Integer; Var MarkText:String) of object;
  743.  
  744.   TSeriesRecalcOptions=set of (rOnDelete, rOnModify, rOnInsert, rOnClear);
  745.  
  746.   TChartSeriesClass=class of TChartSeries;
  747.  
  748.   TFunctionPeriodStyle=( psNumPoints, psRange );
  749.   TFunctionPeriodAlign=( paFirst,paCenter,paLast );
  750.  
  751.   TTeeFunction=class(TComponent)
  752.   private
  753.     FPeriod      : Double;
  754.     FPeriodStyle : TFunctionPeriodStyle;
  755.     FPeriodAlign : TFunctionPeriodAlign;
  756.     FParent      : TChartSeries;
  757.     FUpdating    : Boolean;
  758.     Procedure SetPeriod(Const Value:Double);
  759.     Procedure SetParentSeries(AParent:TChartSeries);
  760.     Procedure SetPeriodAlign(Value:TFunctionPeriodalign);
  761.     Procedure SetPeriodStyle(Value:TFunctionPeriodStyle);
  762.   protected
  763.     CanUsePeriod:Boolean;
  764.     {$IFDEF D1}
  765.     procedure ReadState(Reader: TReader); override;
  766.     {$ELSE}
  767.     procedure SetParentComponent(Value: TComponent); override;
  768.     {$ENDIF}
  769.     Procedure InternalSetPeriod(Const APeriod:Double);
  770.     Procedure AddFunctionXY(YMandatorySource:Boolean; tmpX,tmpY:Double);
  771.     Procedure CalculatePeriod( Source:TChartSeries;
  772.                                Const tmpX:Double;
  773.                                FirstIndex,LastIndex:Longint); virtual;
  774.     Procedure CalculateAllPoints(Source:TChartSeries; NotMandatorySource:TChartValueList); virtual;
  775.     Procedure CalculateByPeriod(Source:TChartSeries; NotMandatorySource:TChartValueList); virtual;
  776.     Function ValueList(ASeries:TChartSeries):TChartValueList;
  777.   public
  778.     MovingFunction:Boolean;
  779.     Constructor Create(AOwner: TComponent); override;
  780.  
  781.     Procedure Assign(Source:TPersistent); override;
  782.     procedure BeginUpdate;
  783.     procedure EndUpdate;
  784.     Procedure ReCalculate;
  785.     Function Calculate(Series:TChartSeries; First,Last:Longint):Double; virtual;
  786.     Function CalculateMany(SeriesList:TList; ValueIndex:Longint):Double; virtual;
  787.     procedure AddPoints(Source:TChartSeries); virtual;
  788.     {$IFNDEF D1}
  789.     function GetParentComponent: TComponent; override;
  790.     {$ENDIF}
  791.     function HasParent: Boolean; override;
  792.     property ParentSeries:TChartSeries read FParent write SetParentSeries;
  793.   published
  794.     property Period:Double read FPeriod write SetPeriod;
  795.     property PeriodAlign:TFunctionPeriodAlign read FPeriodAlign
  796.                                               write SetPeriodAlign default paCenter;
  797.     property PeriodStyle:TFunctionPeriodStyle read FPeriodStyle
  798.                                               write SetPeriodStyle default psNumPoints;
  799.   end;
  800.  
  801.   TChartValueLists=class(TList)
  802.   private
  803.     Function GetValueList(Index:Integer):TChartValueList;
  804.   public
  805.     property ValueList[Index:Integer]:TChartValueList read GetValueList;{$IFNDEF D1}default;{$ENDIF}
  806.   end;
  807.  
  808.   {$IFNDEF D1}
  809.   TChartSeriesStyle=set of ( tssIsTemplate,
  810.                              tssDenyChangeType,
  811.                              tssDenyDelete,
  812.                              tssDenyClone,
  813.                              tssIsPersistent,
  814.                              tssHideDataSource );
  815.   {$ENDIF}
  816.  
  817.   TChartSeries=class(TComponent)
  818.   private
  819.     FActive             : Boolean;
  820.     FColor              : TColor;
  821.     FColorEachPoint     : Boolean;
  822.     FColors             : TList;
  823.     FColorSource        : String;
  824.     FCursor             : TCursor;
  825.     FDataSources        : TList;
  826.     FFirstVisibleIndex  : Longint;
  827.     FGetHorizAxis       : TChartAxis;
  828.     FGetVertAxis        : TChartAxis;
  829.     FLabelsSource       : String;
  830.     FLastVisibleIndex   : Longint;
  831.     FLinkedSeries       : TList;
  832.     FMarks              : TSeriesMarks;
  833.     FParent             : TCustomAxisPanel;
  834.     FPercentFormat      : String;
  835.     FShowInLegend       : Boolean;
  836.     FTempDataSources    : TStringList;
  837.     FTitle              : String;
  838.     FValueFormat        : String;
  839.     FValuesList         : TChartValueLists;
  840.     FX                  : TChartValueList;
  841.     FXLabels            : TList;
  842.     FY                  : TChartValueList;
  843.  
  844.     FHorizAxis          : THorizAxis;
  845.     FCustomHorizAxis    : TChartAxis;
  846.     FCustomVertAxis     : TChartAxis;
  847.     FZOrder             : Integer;
  848.  
  849.     FVertAxis           : TVertAxis;
  850.     FRecalcOptions      : TSeriesRecalcOptions;
  851.  
  852.     FTeeFunction        : TTeeFunction;
  853.     {$IFNDEF D1}
  854.     FStyle              : TChartSeriesStyle; { decision cube }
  855.     {$ENDIF}
  856.  
  857.     { Events }
  858.     FOnBeforeAdd        : TSeriesOnBeforeAdd;
  859.     FOnAfterAdd         : TSeriesOnAfterAdd;
  860.     FOnClearValues      : TSeriesOnClear;
  861.     FOnGetMarkText      : TSeriesOnGetMarkText;
  862.     FBeforeDrawValues   : TNotifyEvent;
  863.     FAfterDrawValues    : TNotifyEvent;
  864.     FOnClick            : TSeriesClick;
  865.     FOnDblClick         : TSeriesClick;
  866.  
  867.     {$IFDEF D3}
  868.     FIdentifier         : String;  { decision cube }
  869.     {$ENDIF}
  870.  
  871.     Procedure InsertLabel(ValueIndex:Longint; Const ALabel:String);
  872.     Function GetMemLabel(Const ALabel:String):PChar;
  873.     Procedure FreeXLabel(ValueIndex:Longint);
  874.     Function GetValue(IsX:Boolean; ValueIndex:Longint):Double;
  875.     procedure ReadData(Reader: TReader);
  876.     procedure WriteData(Writer: TWriter);
  877.     {$IFDEF D3}
  878.     procedure ReadIdentifier(Reader: TReader);
  879.     procedure WriteIdentifier(Writer: TWriter);
  880.     procedure ReadStyle(Reader: TReader);
  881.     procedure WriteStyle(Writer: TWriter);
  882.     {$ENDIF}
  883.     Procedure InternalAddDataSource(Value:TComponent);
  884.     Procedure RemoveAllLinkedSeries;
  885.     Procedure SetTitle(Value:String);
  886.     Procedure SetValueFormat(Const Value:String);
  887.     Procedure SetPercentFormat(Const Value:String);
  888.     Function IsValueFormatStored:Boolean;
  889.     Function IsPercentFormatStored:Boolean;
  890.     Procedure SetHorizAxis(Value:THorizAxis);
  891.     Procedure SetVertAxis(Value:TVertAxis);
  892.     Procedure SetColorSource(Const Value:String);
  893.     Procedure SetLabelsSource(Const Value:String);
  894.     Procedure SetShowInLegend(Value:Boolean);
  895.     Procedure SetCustomHorizAxis(Value:TChartAxis);
  896.     Procedure SetCustomVertAxis(Value:TChartAxis);
  897.     Function GetZOrder:Integer;
  898.     Procedure SetZOrder(Value:Integer);
  899.     Procedure RecalcGetAxis;
  900.   Protected
  901.     IZOrder : Integer;
  902.     Function AddChartValue(Source:TChartSeries; ValueIndex:Longint):Longint; virtual;
  903.     Procedure AddedValue(Source:TChartSeries; ValueIndex:Longint); virtual;
  904.     Procedure AddValues(Source:TChartSeries); virtual;
  905.     Procedure ClearLists; virtual;
  906.     procedure DefineProperties(Filer: TFiler); override;
  907.     Procedure DeletedValue(Source:TChartSeries; ValueIndex:Longint); virtual;
  908.     procedure DoAfterDrawValues; virtual;
  909.     procedure DoBeforeDrawChart; virtual;
  910.     procedure DoBeforeDrawValues; virtual;
  911.     procedure DrawAllValues; virtual;
  912.     Procedure DrawMark(ValueIndex:Longint; Const St:String; APosition:TSeriesMarkPosition); virtual;
  913.     procedure DrawMarks;
  914.     procedure DrawValue(ValueIndex:Longint); virtual;
  915.     Function FirstInZOrder:Boolean;
  916.     Function GetDataSource:TComponent;
  917.     Function GetMarkText(ValueIndex:Longint):String;
  918.     Function GetValueColor(ValueIndex:Longint):TColor; virtual;
  919.     Function GetXLabel(Index:Longint):String; virtual;
  920.     Function GetxValue(Index:Longint):Double; virtual;  { conflicts with c++ wingdi.h }
  921.     Function GetyValue(Index:Longint):Double; virtual;  { conflicts with c++ wingdi.h }
  922.     Procedure Loaded; override;
  923.     procedure Notification( AComponent: TComponent;
  924.                             Operation: TOperation); override;
  925.     Procedure NotifyNewValue(Sender:TChartSeries; ValueIndex:Longint); virtual;
  926.     Procedure NotifyValue(ValueEvent:TValueEvent; ValueIndex:Longint);
  927.     Function MoreSameZOrder:Boolean; virtual;
  928.     Procedure SetActive(Value:Boolean); virtual;
  929.     Procedure SetChartValueList( Var AValueList:TChartValueList;
  930.                                  Value:TChartValueList);
  931.     Procedure SetColorEachPoint(Value:Boolean); virtual;
  932.     Procedure SetDataSource(Value:TComponent);
  933.     procedure SetMarks(Value:TSeriesMarks);
  934.     Procedure SetParentChart(Value:TCustomAxisPanel); virtual;
  935.     Procedure SetRecalcOptions(Value:TSeriesRecalcOptions);
  936.     Procedure SetSeriesColor(AColor:TColor); virtual;
  937.     Procedure SetValueColor(ValueIndex:Longint; AColor:TColor);
  938.     Procedure SetXLabel(Index:Longint; Const AXLabel:String);
  939.     Procedure SetXValue(Index:Longint; Const Value:Double);
  940.     Procedure SetYValue(Index:Longint; Const Value:Double);
  941.     Procedure SetXValues(Value:TChartValueList);
  942.     Procedure SetYValues(Value:TChartValueList);
  943.     {$IFDEF D1}
  944.     Procedure WriteComponents(Writer:TWriter); override;
  945.     procedure ReadState(Reader: TReader); override;
  946.     {$ELSE}
  947.     Procedure GetChildren(Proc:TGetChildProc{$IFDEF D3}; Root:TComponent{$ENDIF}); override;
  948.     procedure SetParentComponent(AParent: TComponent); override;
  949.     {$ENDIF}
  950.   public
  951.     CalcVisiblePoints : Boolean;
  952.     DrawBetweenPoints : Boolean;
  953.     AllowSinglePoint  : Boolean;
  954.     HasZValues        : Boolean;
  955.     StartZ            : Integer;
  956.     MiddleZ           : Integer;
  957.     EndZ              : Integer;
  958.     Constructor Create(AOwner: TComponent); override;
  959.     Destructor Destroy; override;
  960.  
  961.     Function Add(Const AValue:Double; Const ALabel:String {$IFDEF D4}=''{$ENDIF};
  962.                        AColor:TColor{$IFDEF D4}=clTeeColor{$ENDIF}):Longint; virtual;
  963.     Function AddArray(Const Values:array of Double):Longint;
  964.     Procedure AddLinkedSeries(ASeries:TChartSeries);
  965.     Function AddNull(Const ALabel:String {$IFDEF D4}=''{$ENDIF}):Longint; virtual;
  966.     Function AddNullXY(Const X,Y:Double; Const ALabel:String):Longint; virtual;
  967.     Function AddX(Const AXValue:Double; Const ALabel:String {$IFDEF D4}=''{$ENDIF};
  968.                          AColor:TColor{$IFDEF D4}=clTeeColor{$ENDIF}):Longint;
  969.     Function AddXY(Const AXValue,AYValue:Double; Const ALabel:String {$IFDEF D4}=''{$ENDIF};
  970.                          AColor:TColor {$IFDEF D4}=clTeeColor{$ENDIF}):Longint; virtual;
  971.     Function AddY(Const AYValue:Double; Const ALabel:String {$IFDEF D4}=''{$ENDIF};
  972.                          AColor:TColor {$IFDEF D4}=clTeeColor{$ENDIF}):Longint;
  973.  
  974.     procedure Assign(Source:TPersistent); override;
  975.     Function AssociatedToAxis(Axis:TCustomChartAxis):Boolean; virtual;
  976.     Procedure CalcRandomBounds(NumValues:Longint; Var tmpX,StepX,tmpY,MinY,DifY:Double);
  977.     Procedure Clear; virtual;
  978.     Function Count:Longint;
  979.     Function CountLegendItems:Integer; virtual;
  980.     Procedure Delete(ValueIndex:Longint); virtual;
  981.     Procedure FillSampleValues(NumValues:Longint); virtual;
  982.     Procedure GalleryChanged3D(Is3D:Boolean); virtual;
  983.     {$IFNDEF D1}
  984.     function GetParentComponent: TComponent; override;
  985.     {$ENDIF}
  986.     function HasParent: Boolean; override;
  987.     Function IsNull(ValueIndex:Longint):Boolean;
  988.     Function IsValidSourceOf(Value:TChartSeries):Boolean; virtual;
  989.     Function IsValidSeriesSource(Value:TChartSeries):Boolean; virtual;
  990.     Function LegendToValueIndex(LegendIndex:Integer):Integer; virtual;
  991.     Function LegendItemColor(LegendIndex:Longint):TColor; virtual;
  992.     Function LegendString(LegendIndex:Integer; LegendTextStyle:TLegendTextStyle):String; virtual;
  993.     property LinkedSeries:TList read FLinkedSeries;
  994.     Function MaxXValue:Double; virtual;
  995.     Function MaxYValue:Double; virtual;
  996.     Function MaxZValue:Double; virtual;
  997.     Function MinXValue:Double; virtual;
  998.     Function MinYValue:Double; virtual;
  999.     Function MinZValue:Double; virtual;
  1000.     Function NumSampleValues:Longint; virtual;
  1001.     Procedure PrepareForGallery(IsEnabled:Boolean); virtual;
  1002.     Procedure RemoveDataSource(Value:TComponent);
  1003.     Procedure RemoveLinkedSeries(ASeries:TChartSeries);
  1004.     Procedure Repaint;
  1005.     Function VisibleCount:Longint; { <-- Number of VISIBLE points (Last-First+1) }
  1006.  
  1007.     property ValuesLists:TChartValueLists read FValuesList;
  1008.     property XValue[Index:Longint]:Double read GetxValue write SetXValue;
  1009.     property YValue[Index:Longint]:Double read GetyValue write SetYValue;
  1010.  
  1011.     property ZOrder:Integer read GetZOrder write SetZOrder default TeeAutoZOrder;
  1012.     Function MaxMarkWidth:Longint;
  1013.     Function GetEditorClass:String; virtual;
  1014.  
  1015.     Function CalcXPos(ValueIndex:Longint):Integer; virtual;
  1016.     Function CalcXPosValue(Const Value:Double):Longint;
  1017.     Function CalcXSizeValue(Const Value:Double):Longint;
  1018.  
  1019.     Function CalcYPos(ValueIndex:Longint):Integer; virtual;
  1020.     Function CalcYPosValue(Const Value:Double):Longint;
  1021.     Function CalcYSizeValue(Const Value:Double):Longint;
  1022.  
  1023.     Function CalcPosValue(Const Value:Double):Longint;
  1024.  
  1025.     Function XScreenToValue(ScreenPos:Longint):Double;
  1026.     Function YScreenToValue(ScreenPos:Longint):Double;
  1027.  
  1028.     Function XValueToText(Const AValue:Double):String;
  1029.     Function YValueToText(Const AValue:Double):String;
  1030.  
  1031.     Procedure ColorRange( AValueList:TChartValueList;
  1032.                           Const FromValue,ToValue:Double;
  1033.                           AColor:TColor);
  1034.     Procedure CheckDataSource;
  1035.     Procedure AddValue(ValueIndex:Longint); virtual;
  1036.  
  1037.     { Public Properties }
  1038.     property Labels:TList read FXLabels;
  1039.     property XLabel[Index:Longint]:String read GetXLabel write SetXLabel;
  1040.     property ValueMarkText[Index:Longint]:String read GetMarkText;
  1041.  
  1042.     property ValueColor[Index:Longint]:TColor read GetValueColor write SetValueColor;
  1043.     property XValues:TChartValueList read FX write SetXValues;
  1044.     property YValues:TChartValueList read FY write SetYValues;
  1045.  
  1046.     Function GetYValueList(AListName:String):TChartValueList; virtual;
  1047.     property GetVertAxis:TChartAxis read FGetVertAxis;
  1048.     property GetHorizAxis:TChartAxis read FGetHorizAxis;
  1049.     Function MarkPercent(ValueIndex:Longint; AddTotal:Boolean):String;
  1050.     Function Clicked(x,y:Integer):Longint; virtual;
  1051.     Procedure RefreshSeries;
  1052.     property FirstValueIndex:Longint read FFirstVisibleIndex;
  1053.     property LastValueIndex:Longint read FLastVisibleIndex;
  1054.     Function GetOriginValue(ValueIndex:Longint):Double; virtual;
  1055.     Function GetMarkValue(ValueIndex:Longint):Double; virtual;
  1056.     Procedure AssignValues(Source:TChartSeries);
  1057.     Function SameClass(tmpSeries:TChartSeries):Boolean;
  1058.     Function PointOrigin(ValueIndex:Longint; SumAll:Boolean):Double; virtual;
  1059.     Function YMandatory:Boolean;
  1060.     Function MandatoryValueList:TChartValueList; virtual;
  1061.     Function DrawValuesForward:Boolean; virtual;
  1062.     Function DrawSeriesForward(ValueIndex:Longint):Boolean; virtual;
  1063.     procedure SwapValueIndex(a,b:Longint); virtual;
  1064.     property RecalcOptions: TSeriesRecalcOptions read FRecalcOptions
  1065.                                                  write SetRecalcOptions
  1066.                                        default [ rOnDelete,
  1067.                                                  rOnModify,
  1068.                                                  rOnInsert,
  1069.                                                  rOnClear];
  1070.     Procedure CalcZOrder; virtual;
  1071.     Procedure DoSeriesMouseMove(Shift: TShiftState; X, Y: Integer); virtual;
  1072.     Function DoSeriesClick( Sender:TChartSeries;
  1073.                             ValueIndex:Longint;
  1074.                             Button:TMouseButton;
  1075.                             Shift: TShiftState; X, Y: Integer):Boolean; virtual;
  1076.     Procedure DoSeriesMouseUp( Button:TMouseButton;
  1077.                                Shift: TShiftState; X, Y: Integer); virtual;
  1078.  
  1079.     Function GetCursorValueIndex:Longint;
  1080.     Procedure GetCursorValues(Var x,y:Double);
  1081.     Procedure ClearTempValue(ValueList:TChartValueList); virtual;
  1082.     Procedure DrawLegend(ValueIndex:Longint; Const Rect:TRect); virtual;
  1083.     Procedure DrawLegendShape(ValueIndex:Longint; Const Rect:TRect); virtual;
  1084.     Procedure PrepareLegendCanvas( ValueIndex:Longint; Var BackColor:TColor;
  1085.                                    Var BrushStyle:TBrushStyle); virtual;
  1086.  
  1087.     Procedure CalcHorizMargins(Var LeftMargin,RightMargin:Integer); virtual;
  1088.     Procedure CalcVerticalMargins(Var TopMargin,BottomMargin:Integer); virtual;
  1089.  
  1090.     Function UseAxis:Boolean; virtual;
  1091.     procedure SetFunction(AFunction:TTeeFunction); virtual;
  1092.  
  1093.     Procedure CalcFirstLastVisibleIndex;
  1094.  
  1095.     { other }
  1096.     Function CreateChartPen:TChartPen;
  1097.     Procedure CanvasChanged(Sender:TObject); virtual;
  1098.     property DataSources:TList read FDataSources;
  1099.     property FunctionType:TTeeFunction read FTeeFunction;
  1100.     Procedure SetLongintProperty(Var Variable:Longint; Value:Longint);
  1101.     Procedure SetIntegerProperty(Var Variable:Integer; Value:Integer);
  1102.     Procedure SetStringProperty(Var Variable:String; Const Value:String);
  1103.     Procedure SetBooleanProperty(Var Variable:Boolean; Value:Boolean);
  1104.     Procedure SetColorProperty(Var Variable:TColor; Value:TColor);
  1105.     Procedure SetDoubleProperty(Var Variable:Double; Const Value:Double);
  1106.     Procedure CheckOtherSeries(Source:TChartSeries);
  1107.     Procedure GetBitmapEditor(ABitmap:TBitmap); virtual;
  1108.     Procedure ReplaceList(OldList,NewList:TChartValueList);
  1109.     { DSS, hidden }
  1110.     {$IFDEF D3}
  1111.     property Identifier:String read FIdentifier write FIdentifier;
  1112.     property Style:TChartSeriesStyle read FStyle write FStyle default [];
  1113.     {$ENDIF}
  1114.     property CustomHorizAxis:TChartAxis read FCustomHorizAxis write SetCustomHorizAxis;
  1115.     property CustomVertAxis:TChartAxis read FCustomVertAxis write SetCustomVertAxis;
  1116.   published
  1117.     property Active:Boolean read FActive write SetActive default True;
  1118.     property ColorEachPoint:Boolean read FColorEachPoint write SetColorEachPoint default False;
  1119.     property ColorSource:String read FColorSource write SetColorSource;
  1120.     property Cursor:TCursor read FCursor write FCursor default crDefault;
  1121.     property HorizAxis:THorizAxis read FHorizAxis write SetHorizAxis default aBottomAxis;
  1122.     property Marks:TSeriesMarks read FMarks write SetMarks;
  1123.     property ParentChart:TCustomAxisPanel read FParent write SetParentChart stored False;
  1124.     { datasource below parentchart }
  1125.     property DataSource:TComponent read GetDataSource write SetDataSource;
  1126.     property PercentFormat:String read FPercentFormat write SetPercentFormat stored IsPercentFormatStored;
  1127.     property SeriesColor:TColor read FColor write SetSeriesColor default clTeeColor;
  1128.     property ShowInLegend:Boolean read FShowInLegend write SetShowInLegend default True;
  1129.     property Title:String read FTitle write SetTitle;
  1130.     property ValueFormat:String read FValueFormat write SetValueFormat stored IsValueFormatStored;
  1131.     property VertAxis:TVertAxis read FVertAxis write SetVertAxis default aLeftAxis;
  1132.     property XLabelsSource:String read FLabelsSource write SetLabelsSource;
  1133.  
  1134.     { events }
  1135.     property AfterDrawValues:TNotifyEvent read FAfterDrawValues
  1136.                                            write FAfterDrawValues;
  1137.     property BeforeDrawValues:TNotifyEvent read FBeforeDrawValues
  1138.                                            write FBeforeDrawValues;
  1139.     property OnAfterAdd:TSeriesOnAfterAdd read FOnAfterAdd write FOnAfterAdd;
  1140.     property OnBeforeAdd:TSeriesOnBeforeAdd read FOnBeforeAdd write FOnBeforeAdd;
  1141.     property OnClearValues:TSeriesOnClear read FOnClearValues
  1142.                                           write FOnClearValues;
  1143.     property OnClick:TSeriesClick read FOnClick write FOnClick;
  1144.     property OnDblClick:TSeriesClick read FOnDblClick write FOnDblClick;
  1145.     property OnGetMarkText:TSeriesOnGetMarkText read FOnGetMarkText
  1146.                                                 write FOnGetMarkText;
  1147.   end;
  1148.  
  1149.   TTeeFunctionClass=class of TTeeFunction;
  1150.  
  1151. Const  { see initialization section at bottom of this unit }
  1152.   TeeAxisClickGap       : Longint=3;  { minimum pixels distance to trigger axis click }
  1153.   TeeDefaultCapacity    : Longint=0;  { default TList.Capacity to speed-up Lists }
  1154.  
  1155. implementation
  1156.  
  1157. Uses TeeConst;
  1158.  
  1159. { TChartBrush }
  1160. Constructor TChartBrush.Create(OnChangeEvent:TNotifyEvent);
  1161. Begin
  1162.   inherited Create;
  1163.   Color:=clTeeColor;
  1164.   OnChange:=OnChangeEvent;
  1165. end;
  1166.  
  1167. { TChartValueList }
  1168. Constructor TChartValueList.Create(AOwner:TChartSeries; Const AName:String);
  1169. Begin
  1170.   inherited Create;
  1171.   IDirtyStats:=True;
  1172.   FMultiplier:=1;
  1173.   FOwner:=AOwner;
  1174.   FOwner.FValuesList.Add(Self);
  1175.   FName:=AName;
  1176.   FList:=TList.Create;
  1177.   ClearValues;
  1178. end;
  1179.  
  1180. Destructor TChartValueList.Destroy;
  1181. Begin
  1182.   FList.Free;
  1183.   inherited Destroy;
  1184. End;
  1185.  
  1186. Function TChartValueList.First:Double;
  1187. Begin
  1188.   result:=GetValue(0);
  1189. end;
  1190.  
  1191. Function TChartValueList.Count:Longint;
  1192. Begin
  1193.   result:=FList.Count; { <-- virtual }
  1194. end;
  1195.  
  1196. Function TChartValueList.Last:Double;
  1197. Begin
  1198.   result:=GetValue(Count-1);
  1199. end;
  1200.  
  1201. Procedure TChartValueList.Delete(ValueIndex:Longint);
  1202. Begin
  1203.   Dispose(PChartValue(FList[ValueIndex]));  { <- virtual }
  1204.   FList.Delete(ValueIndex);
  1205.   IDirtyStats:=True;
  1206. end;
  1207.  
  1208. Procedure TChartValueList.InsertChartValue(ValueIndex:Longint; Const Value:TChartValue);
  1209. Var p : PChartValue;
  1210. Begin
  1211.   New(p);
  1212.   p^:=Value;
  1213.   FList.Insert(ValueIndex,p);  { <- virtual }
  1214.   IDirtyStats:=True;
  1215. end;
  1216.  
  1217. Function TChartValueList.AddChartValue(Const Value:TChartValue):Longint;
  1218. Var t : Longint;
  1219.     p : PChartValue;
  1220. Begin
  1221.   New(p);    { virtual }
  1222.   p^:=Value;
  1223.   if FOrder=loNone then result:=FList.Add(p)
  1224.   else
  1225.   begin
  1226.     t:=FList.Count-1;
  1227.     if (t=-1) or
  1228.        ( (FOrder=loAscending) and (Value>=PChartValue(FList[t])^) ) or
  1229.        ( (FOrder=loDescending) and (Value<=PChartValue(FList[t])^) ) then
  1230.           result:=FList.Add(p)
  1231.     else
  1232.     Begin
  1233.       if FOrder=loAscending then
  1234.          While (t>=0) and (PChartValue(FList[t])^>Value) do Dec(t)
  1235.       else
  1236.          While (t>=0) and (PChartValue(FList[t])^<Value) do Dec(t);
  1237.       result:=t+1;
  1238.       FList.Insert(result,p);
  1239.     end;
  1240.   end;
  1241.   IDirtyStats:=True;
  1242. end;
  1243.  
  1244. Procedure TChartValueList.SetMultiplier(Const Value:Double);
  1245. Begin
  1246.   if Value<>FMultiplier then
  1247.   begin
  1248.     FMultiplier:=Value;
  1249.     IDirtyStats:=True;
  1250.     FOwner.NotifyValue(veRefresh,0);
  1251.     FOwner.Repaint;
  1252.   end;
  1253. end;
  1254.  
  1255. Function TChartValueList.GetValue(ValueIndex:Longint):Double;
  1256. begin
  1257.   result:=TChartValue(FList[ValueIndex]^)*FMultiplier; { virtual }
  1258. end;
  1259.  
  1260. Function TChartValueList.Locate( Const Value :Double ):Longint;
  1261. Var t : Longint;
  1262. Begin
  1263.   for t:=0 to Count-1 do
  1264.   if GetValue(t)=Value then
  1265.   begin
  1266.     result:=t;
  1267.     exit;
  1268.   end;
  1269.   result:=-1;
  1270. end;
  1271.  
  1272. Procedure TChartValueList.SetValue(ValueIndex:Longint; Const AValue:Double);
  1273. begin
  1274.   PChartValue(FList[ValueIndex])^:=AValue; { virtual }
  1275.   IDirtyStats:=True;
  1276.   FOwner.NotifyValue(veModify,ValueIndex);
  1277. end;
  1278.  
  1279. Function TChartValueList.GetMaxValue:Double;
  1280. begin
  1281.   if IDirtyStats then RecalcStats;
  1282.   result:=FMaxValue;
  1283. end;
  1284.  
  1285. Function TChartValueList.GetMinValue:Double;
  1286. begin
  1287.   if IDirtyStats then RecalcStats;
  1288.   result:=FMinValue;
  1289. end;
  1290.  
  1291. Function TChartValueList.GetTotal:Double;
  1292. begin
  1293.   if IDirtyStats then RecalcStats;
  1294.   result:=FTotal;
  1295. end;
  1296.  
  1297. Function TChartValueList.GetTotalABS:Double;
  1298. begin
  1299.   if IDirtyStats then RecalcStats;
  1300.   result:=FTotalABS;
  1301. end;
  1302.  
  1303. Procedure TChartValueList.RecalcStats;
  1304. var t        : Longint;
  1305.     tmpValue : Double;
  1306. Begin
  1307.   if Count>0 then
  1308.   begin
  1309.     tmpValue:=GetValue(0);
  1310.     FMinValue:=tmpValue;
  1311.     FMaxValue:=tmpValue;
  1312.     FTotal:=tmpValue;
  1313.     FTotalABS:=Abs(tmpValue);
  1314.     for t:=1 to Count-1 do
  1315.     Begin
  1316.       tmpValue:=GetValue(t);
  1317.       if tmpValue<FMinValue then FMinValue:=tmpValue else
  1318.       if tmpValue>FMaxValue then FMaxValue:=tmpValue;
  1319.       FTotal:=FTotal+tmpValue;
  1320.       FTotalABS:=FTotalABS+Abs(tmpValue);
  1321.     end;
  1322.   end
  1323.   else
  1324.   begin
  1325.     FMinValue:=0;
  1326.     FMaxValue:=0;
  1327.     FTotal:=0;
  1328.     FTotalABS:=0;
  1329.   end;
  1330.   IDirtyStats:=False;
  1331. end;
  1332.  
  1333. procedure TChartValueList.SetDateTime(Value:Boolean);
  1334. Begin
  1335.   FOwner.SetBooleanProperty(FDateTime,Value);
  1336. end;
  1337.  
  1338. Procedure TChartValueList.ClearValues;
  1339. Var t : Longint;
  1340. Begin
  1341.   for t:=0 to FList.Count-1 do Dispose(PChartValue(FList[t])); { virtual }
  1342.   FList.Clear;
  1343.   {$IFDEF D1}
  1344.   if TeeDefaultCapacity<16384 then
  1345.   {$ENDIF}
  1346.   FList.Capacity:=TeeDefaultCapacity;
  1347.   IDirtyStats:=True;
  1348. end;
  1349.  
  1350. Procedure TChartValueList.Scroll;
  1351. var t      : Longint;
  1352.     tmpVal : PChartValue;
  1353. Begin
  1354.   With FList do  { virtual }
  1355.   if Count>0 then
  1356.   Begin
  1357.     tmpVal:=First;
  1358.     for t:=1 to Count-1 do Items[t-1]:=Items[t];
  1359.     Items[Count-1]:=tmpVal;
  1360.   end;
  1361. end;
  1362.  
  1363. Procedure TChartValueList.SetValueSource(Const Value:String);
  1364. Begin
  1365.   if FValueSource<>Value then
  1366.   begin
  1367.     FValueSource:=Value;
  1368.     FOwner.CheckDataSource;
  1369.   end;
  1370. end;
  1371.  
  1372. Procedure TChartValueList.FillSequence;
  1373. var t : Longint;
  1374. begin
  1375.   for t:=0 to Count-1 do SetValue(t,t);
  1376. end;
  1377.  
  1378. procedure TChartValueList.Sort;
  1379.  
  1380.   Function CompareValueIndex(a,b:Longint):Longint;
  1381.   var tmpA : Double;
  1382.       tmpB : Double;
  1383.   begin
  1384.     tmpA:=GetValue(a);
  1385.     tmpB:=GetValue(b);
  1386.     if tmpA<tmpB then result:=-1 else
  1387.     if tmpA>tmpB then result:= 1 else result:= 0;
  1388.     if FOrder=loDescending then result:=-result;
  1389.   end;
  1390.  
  1391.   procedure PrivateSort(l,r:longint);
  1392.   var i : Longint;
  1393.       j : Longint;
  1394.       x : Longint;
  1395.   begin
  1396.     i:=l;
  1397.     j:=r;
  1398.     x:=(i+j) shr 1;
  1399.     while i<j do
  1400.     begin
  1401.       while CompareValueIndex(i,x)<0 do inc(i);
  1402.       while CompareValueIndex(x,j)<0 do dec(j);
  1403.       if i<j then
  1404.       begin
  1405.         Owner.SwapValueIndex(i,j);
  1406.         if i=x then x:=j else if j=x then x:=i;
  1407.       end;
  1408.       if i<=j then
  1409.       begin
  1410.         inc(i);
  1411.         dec(j)
  1412.       end;
  1413.     end;
  1414.     if l<j then PrivateSort(l,j);
  1415.     if i<r then PrivateSort(i,r);
  1416.   end;
  1417.  
  1418. begin
  1419.   if FOrder<>loNone then PrivateSort(0,Count-1);
  1420. end;
  1421.  
  1422. Procedure TChartValueList.Assign(Source:TPersistent);
  1423. begin
  1424.   if Source is TChartValueList then
  1425.   With TChartValueList(Source) do
  1426.   begin
  1427.     Self.FOrder      :=FOrder;
  1428.     Self.FDateTime   :=FDateTime;
  1429.     Self.FMultiplier :=FMultiplier;
  1430.     Self.FValueSource:=FValueSource;
  1431.   end;
  1432. end;
  1433.  
  1434. { TSeriesMarksPosition }
  1435. Procedure TSeriesMarkPosition.Assign(Source:TSeriesMarkPosition);
  1436. begin
  1437.   ArrowFrom :=Source.ArrowFrom;
  1438.   ArrowTo   :=Source.ArrowTo;
  1439.   LeftTop   :=Source.LeftTop;
  1440.   Height    :=Source.Height;
  1441.   Width     :=Source.Width;
  1442. end;
  1443.  
  1444. Function TSeriesMarkPosition.Bounds:TRect;
  1445. begin
  1446.   result:=Classes.Bounds(LeftTop.X,LeftTop.Y,Width,Height);
  1447. end;
  1448.  
  1449. { TSeriesMarksPositions }
  1450. Procedure TSeriesMarksPositions.SetPosition(Index:Integer; APosition:TSeriesMarkPosition);
  1451. begin
  1452.   While Index>=Count do Add(nil);
  1453.   if Items[Index]=nil then Items[Index]:=TSeriesMarkPosition.Create;
  1454.   With Position[Index] do
  1455.   begin
  1456.     Custom:=True;
  1457.     Assign(APosition);
  1458.   end;
  1459. end;
  1460.  
  1461. Function TSeriesMarksPositions.GetPosition(Index:Integer):TSeriesMarkPosition;
  1462. begin
  1463.   if (Index<Count) and (Items[Index]<>nil) then result:=TSeriesMarkPosition(Items[Index])
  1464.                                            else result:=nil
  1465. end;
  1466.  
  1467. Procedure TSeriesMarksPositions.Automatic(Index:Integer);
  1468. begin
  1469.   if (Index<Count) and (Items[Index]<>nil) then Position[Index].Custom:=False;
  1470. end;
  1471.  
  1472. { TSeriesMarks }
  1473. Constructor TSeriesMarks.Create(AOwner:TChartSeries);
  1474. Begin
  1475.   inherited Create;
  1476.   FParent         := AOwner;
  1477.   FMarkerStyle    := smsLabel;
  1478.   FFrame          := FParent.CreateChartPen;
  1479.   FBackColor      := ChartMarkColor;
  1480.   FArrow          := TChartArrowPen.Create(FParent.CanvasChanged);
  1481.   FArrowLength    := 8;
  1482.   FFont           := CreateDefaultFont(FParent.CanvasChanged);
  1483.   FPositions      := TSeriesMarksPositions.Create;
  1484. end;
  1485.  
  1486. Procedure TSeriesMarks.Assign(Source:TPersistent);
  1487. Begin
  1488.   if Source is TSeriesMarks then
  1489.   With TSeriesMarks(Source) do
  1490.   Begin
  1491.     Self.FArrow.Assign(FArrow);
  1492.     Self.FArrowLength:=FArrowLength;
  1493.     Self.FBackColor  :=FBackColor;
  1494.     Self.FBackTransparent:=FBackTransparent;
  1495.     Self.FClip       :=FClip;
  1496.     Self.FFrame.Assign(FFrame);
  1497.     Self.FFont.Assign(FFont);
  1498.     Self.FMarkerStyle:=FMarkerStyle;
  1499.     Self.FVisible    :=FVisible;
  1500.   end
  1501.   else inherited Assign(Source);
  1502. end;
  1503.  
  1504. Function TSeriesMarks.IsFontStored:Boolean;
  1505. begin
  1506.   result:=not IsDefaultFont(FFont);
  1507. end;
  1508.  
  1509. Procedure TSeriesMarks.SetVisible(Value:Boolean);
  1510. Begin
  1511.   FParent.SetBooleanProperty(FVisible,Value);
  1512. end;
  1513.  
  1514. Procedure TSeriesMarks.SetFrame(Value:TChartPen);
  1515. begin
  1516.   FFrame.Assign(Value);
  1517. end;
  1518.  
  1519. Procedure TSeriesMarks.SetArrow(Value:TChartArrowPen);
  1520. begin
  1521.   FArrow.Assign(Value);
  1522. end;
  1523.  
  1524. Procedure TSeriesMarks.SetArrowLength(Value:Integer);
  1525. Begin
  1526.   FParent.SetIntegerProperty(FArrowLength,Value);
  1527. end;
  1528.  
  1529. Procedure TSeriesMarks.SetBackColor(Value:TColor);
  1530. Begin
  1531.   FParent.SetColorProperty(FBackColor,Value);
  1532. end;
  1533.  
  1534. Procedure TSeriesMarks.SetBackTransparent(Value:Boolean);
  1535. Begin
  1536.   FParent.SetBooleanProperty(FBackTransparent,Value);
  1537. end;
  1538.  
  1539. Function TSeriesMarks.Clicked(X,Y:Integer):Integer;
  1540. var t : Integer;
  1541. begin
  1542.   if (FParent.ParentChart<>nil) then
  1543.       FParent.ParentChart.Canvas.Calculate2DPosition(x,y,ZPosition);
  1544.   with FPositions do
  1545.   for t:=0 to Count-1 do
  1546.   if (Position[t]<>nil) and PtInRect(Position[t].Bounds,Point(X,Y)) then
  1547.   begin
  1548.     result:=t;
  1549.     Exit;
  1550.   end;
  1551.   result:=-1;
  1552. end;
  1553.  
  1554. Procedure TSeriesMarks.UsePosition( Index:Integer; Var MarkPosition:TSeriesMarkPosition);
  1555. var tmp : TSeriesMarkPosition;
  1556. begin
  1557.   with FPositions do
  1558.   begin
  1559.     while Index>=Count do Add(nil);
  1560.     if Items[Index]=nil then
  1561.     begin
  1562.       tmp:=TSeriesMarkPosition.Create;
  1563.       tmp.Custom:=False;
  1564.       Items[Index]:=tmp;
  1565.     end;
  1566.     tmp:=Position[Index];
  1567.     if tmp.Custom then MarkPosition.Assign(tmp)
  1568.                   else tmp.Assign(MarkPosition);
  1569.   end;
  1570. end;
  1571.  
  1572. Procedure TSeriesMarks.ClearPositions;
  1573. var t : Integer;
  1574. begin
  1575.   With FPositions do
  1576.   begin
  1577.     for t:=0 to Count-1 do Position[t].Free;
  1578.     Clear;
  1579.   end;
  1580. end;
  1581.  
  1582. Destructor TSeriesMarks.Destroy;
  1583. begin
  1584.   FFont.Free;
  1585.   FFrame.Free;
  1586.   FArrow.Free;
  1587.   ClearPositions;
  1588.   FPositions.Free;
  1589.   inherited Destroy;
  1590. end;
  1591.  
  1592. Procedure TSeriesMarks.SetFont(Value:TFont);
  1593. begin
  1594.   FFont.Assign(Value);
  1595. end;
  1596.  
  1597. Procedure TSeriesMarks.SetStyle(Value:TSeriesMarksStyle);
  1598. Begin
  1599.   if FMarkerStyle<>Value then
  1600.   begin
  1601.     FMarkerStyle:=Value;
  1602.     FParent.Repaint;
  1603.   end;
  1604. end;
  1605.  
  1606. Procedure TSeriesMarks.SetClip(Value:Boolean);
  1607. Begin
  1608.   FParent.SetBooleanProperty(FClip,Value);
  1609. end;
  1610.  
  1611. Procedure TSeriesMarks.Draw(Index:Integer; AColor:TColor; Const St:String; APosition:TSeriesMarkPosition);
  1612.  
  1613.   Procedure DrawMarkText;
  1614.   Var tmpPosRow    : Integer;
  1615.       tmpCenter    : Integer;
  1616.  
  1617.     Procedure DrawLine(Const LineSt:String);
  1618.     begin
  1619.       With FParent.ParentChart.Canvas do
  1620.       if Supports3DText then TextOut3D(tmpCenter,tmpPosRow,ZPosition,LineSt)
  1621.                         else TextOut(tmpCenter,tmpPosRow,LineSt);
  1622.     end;
  1623.  
  1624.   var tmpSt : String;
  1625.       i     : Integer;
  1626.       tmpRowHeight : Integer;
  1627.   begin
  1628.     With APosition do
  1629.     begin
  1630.       tmpCenter:=LeftTop.X+(Width div 2);
  1631.       tmpPosRow:=LeftTop.Y;
  1632.     end;
  1633.     i:=AnsiPos(TeeLineSeparator,St);
  1634.     if i>0 then
  1635.     begin
  1636.       tmpSt:=St;
  1637.       tmpRowHeight:=FParent.ParentChart.Canvas.FontHeight;
  1638.       Repeat
  1639.         DrawLine(Copy(tmpSt,1,i-1));
  1640.         tmpSt:=Copy(tmpSt,i+1,255);
  1641.         Inc(tmpPosRow,tmpRowHeight);
  1642.         i:=AnsiPos(TeeLineSeparator,tmpSt);
  1643.       Until i=0;
  1644.       if tmpSt<>'' then DrawLine(tmpSt);
  1645.     end
  1646.     else DrawLine(St);
  1647.   end;
  1648.  
  1649. Const ArrowColors:Array[Boolean] of TColor=(clBlack,clWhite);
  1650.       BrushStyles:Array[Boolean] of TBrushStyle=(bsSolid,bsClear);
  1651. var tmpPos2D : TPoint;
  1652.     tmpDifX  : Integer;
  1653.     tmpDifY  : Integer;
  1654.     tmp3D    : Boolean;
  1655. begin
  1656.   UsePosition(Index,APosition);
  1657.   with FParent,ParentChart.Canvas do
  1658.   Begin
  1659.     tmp3D:=ParentChart.View3D;
  1660.     if FArrow.Visible then
  1661.     Begin
  1662.       Pen.Assign(FArrow);
  1663.       Brush.Style:=bsClear;
  1664.       if TeeCheckMarkArrowColor then
  1665.          if (Pen.Color=AColor) or (Pen.Color=ParentChart.Color) then
  1666.             Pen.Color:=ArrowColors[ParentChart.Color=clBlack];
  1667.       With APosition do
  1668.       if tmp3D then LineWithZ(ArrowFrom.X,ArrowFrom.Y,ArrowTo.X,ArrowTo.Y,ZPosition)
  1669.                else Line(ArrowFrom.X,ArrowFrom.Y,ArrowTo.X,ArrowTo.Y);
  1670.     end;
  1671.  
  1672.     if tmp3D and (not Supports3DText) then
  1673.     With APosition do
  1674.     begin
  1675.       tmpDifX:=ArrowTo.X-LeftTop.X;
  1676.       tmpDifY:=ArrowTo.Y-LeftTop.Y;
  1677.       tmpPos2D:=Calculate3DPosition(ArrowTo.X,ArrowTo.Y,ZPosition);
  1678.       LeftTop:=Point(tmpPos2D.X-tmpDifX,tmpPos2D.Y-tmpDifY);
  1679.     end;
  1680.  
  1681.     if FFrame.Visible or (not FBackTransparent) then
  1682.     Begin
  1683.       Brush.Color:=FBackColor;
  1684.       Brush.Style:=BrushStyles[FBackTransparent];
  1685.       AssignVisiblePen(FFrame);
  1686.       if tmp3D and Supports3DText then
  1687.          RectangleWithZ(APosition.Bounds,Succ(ZPosition))
  1688.       else
  1689.          DoRectangle(APosition.Bounds);
  1690.       if FFrame.Visible then Inc(APosition.LeftTop.Y,FFrame.Width);
  1691.     end;
  1692.     Brush.Style:=bsClear;
  1693.     TextAlign:=TA_CENTER;
  1694.     DrawMarkText;
  1695.     TextAlign:=TA_LEFT;
  1696.   end;
  1697. end;
  1698.  
  1699. { TTeeFunction }
  1700. Constructor TTeeFunction.Create(AOwner: TComponent);
  1701. begin
  1702.   inherited Create(AOwner);
  1703.   CanUsePeriod:=True;
  1704.   FPeriodAlign:=paCenter;
  1705.   FPeriodStyle:=psNumPoints;
  1706.   FPeriod:=0; { = calculate with all points (no period) }
  1707. end;
  1708.  
  1709. Procedure TTeeFunction.BeginUpdate;
  1710. begin
  1711.   FUpdating:=True;
  1712. end;
  1713.  
  1714. Procedure TTeeFunction.EndUpdate;
  1715. begin
  1716.   if FUpdating then
  1717.   begin
  1718.     FUpdating:=False;
  1719.     Recalculate;
  1720.   end;
  1721. end;
  1722.  
  1723. Procedure TTeeFunction.Recalculate;
  1724. begin
  1725.   if not FUpdating then
  1726.      if Assigned(FParent) then FParent.CheckDataSource;
  1727. end;
  1728.  
  1729. Function TTeeFunction.Calculate(Series:TChartSeries; First,Last:Longint):Double;
  1730. begin
  1731.   result:=0; { abstract }
  1732. end;
  1733.  
  1734. Function TTeeFunction.ValueList(ASeries:TChartSeries):TChartValueList;
  1735. var tmp:String;
  1736. begin
  1737.   tmp:=ParentSeries.MandatoryValueList.ValueSource;
  1738.   With ASeries do
  1739.   if tmp='' then result:=MandatoryValueList
  1740.             else result:=GetYValueList(tmp);
  1741. end;
  1742.  
  1743. Procedure TTeeFunction.CalculateAllPoints( Source:TChartSeries;
  1744.                                            NotMandatorySource:TChartValueList);
  1745. var tmpX : Double;
  1746.     tmpY : Double;
  1747. begin
  1748.   with ParentSeries do
  1749.   begin
  1750.     tmpY:=Calculate(Source,TeeAllValues,TeeAllValues);
  1751.     if not AllowSinglePoint then
  1752.     begin
  1753.       tmpX:=NotMandatorySource.MinValue;
  1754.       AddFunctionXY(Source.YMandatory,tmpX,tmpY);
  1755.       tmpX:=NotMandatorySource.MaxValue;
  1756.       AddFunctionXY(Source.YMandatory,tmpX,tmpY);
  1757.     end
  1758.     else { centered point }
  1759.     if (not Source.YMandatory) and (ParentSeries.YMandatory) then
  1760.     begin
  1761.       With NotMandatorySource do tmpX:=MinValue+0.5*(MaxValue-MinValue);
  1762.       AddXY(tmpX,tmpY{$IFNDEF D4},'', clTeeColor{$ENDIF});
  1763.     end
  1764.     else
  1765.     begin
  1766.       With NotMandatorySource do tmpX:=MinValue+0.5*(MaxValue-MinValue);
  1767.       if ParentSeries.YMandatory then
  1768.          AddFunctionXY(Source.YMandatory,tmpX,tmpY)
  1769.       else
  1770.          AddXY(tmpY,tmpX{$IFNDEF D4},'', clTeeColor{$ENDIF})
  1771.     end;
  1772.   end;
  1773. end;
  1774.  
  1775. Procedure TTeeFunction.CalculatePeriod( Source:TChartSeries;
  1776.                                         Const tmpX:Double;
  1777.                                         FirstIndex,LastIndex:Longint);
  1778. begin
  1779.   AddFunctionXY( Source.YMandatory, tmpX, Calculate(Source,FirstIndex,LastIndex) );
  1780. end;
  1781.  
  1782. Procedure TTeeFunction.CalculateByPeriod( Source:TChartSeries;
  1783.                                           NotMandatorySource:TChartValueList);
  1784. var tmpX     : Double;
  1785.     tmpCount : Longint;
  1786.     tmpFirst : Longint;
  1787.     tmpLast  : Longint;
  1788.     tmpBreakPeriod:Double;
  1789.     PosFirst : Double;
  1790.     PosLast  : Double;
  1791.     tmpStep  : TDateTimeStep;
  1792.     tmpCalc  : Boolean;
  1793. begin
  1794.   With ParentSeries do
  1795.   begin
  1796.     tmpFirst:=0;
  1797.     tmpCount:=Source.Count;
  1798.     tmpBreakPeriod:=NotMandatorySource.Value[tmpFirst];
  1799.     tmpStep:=FindDateTimeStep(FPeriod);
  1800.     Repeat
  1801.       PosLast:=0;
  1802.       if FPeriodStyle=psNumPoints then
  1803.       begin
  1804.         tmpLast:=tmpFirst+Round(FPeriod)-1;
  1805.         With NotMandatorySource do
  1806.         begin
  1807.           PosFirst:=Value[tmpFirst];
  1808.           if tmpLast<tmpCount then PosLast:=Value[tmpLast];
  1809.         end;
  1810.       end
  1811.       else
  1812.       begin
  1813.         tmpLast:=tmpFirst;
  1814.         PosFirst:=tmpBreakPeriod;
  1815.         GetHorizAxis.IncDecDateTime(True,tmpBreakPeriod,FPeriod,tmpStep);
  1816.         PosLast:=tmpBreakPeriod-(FPeriod*0.001);
  1817.         While tmpLast<(tmpCount-1) do
  1818.           if NotMandatorySource.Value[tmpLast+1]<tmpBreakPeriod then Inc(tmpLast)
  1819.                                                                 else break;
  1820.       end;
  1821.       tmpCalc:=False;
  1822.       if tmpLast<tmpCount then
  1823.       begin
  1824.         { align periods }
  1825.         if FPeriodAlign=paFirst then tmpX:=PosFirst else
  1826.         if FPeriodAlign=paLast then tmpX:=PosLast else
  1827.                                     tmpX:=(PosFirst+PosLast)*0.5;
  1828.         if (FPeriodStyle=psRange) and (NotMandatorySource.Value[tmpFirst]<tmpBreakPeriod) then
  1829.            tmpCalc:=True;
  1830.         if (FPeriodStyle=psNumPoints) or tmpCalc then
  1831.            CalculatePeriod(Source,tmpX,tmpFirst,tmpLast)
  1832.         else
  1833.            AddFunctionXY( Source.YMandatory, tmpX, 0 );
  1834.       end;
  1835.       if (FPeriodStyle=psNumPoints) or tmpCalc then tmpFirst:=tmpLast+1;
  1836.     until tmpFirst>tmpCount-1;
  1837.   end;
  1838. end;
  1839.  
  1840. Procedure TTeeFunction.AddFunctionXY(YMandatorySource:Boolean; tmpX,tmpY:Double);
  1841. begin
  1842.   if not YMandatorySource then SwapDouble(tmpX,tmpY);
  1843.   ParentSeries.AddXY( tmpX, tmpY{$IFNDEF D4},'', clTeeColor{$ENDIF});
  1844. end;
  1845.  
  1846. procedure TTeeFunction.AddPoints(Source:TChartSeries);
  1847. Var NotMandatorySource : TChartValueList;
  1848.     YMandatorySource   : Boolean;
  1849.  
  1850.     Procedure CalculateMovingFunction;
  1851.     Var t : Longint;
  1852.         P : Longint;
  1853.     begin
  1854.       P:=Round(FPeriod);
  1855.       for t:=P-1 to Source.Count-1 do
  1856.           AddFunctionXY( Source.YMandatory, NotMandatorySource[t], Calculate(Source,t-P+1,t));
  1857.     end;
  1858.  
  1859.     Procedure CalculateFunctionMany;
  1860.     var t    : Longint;
  1861.         tmpX : Double;
  1862.         tmpY : Double;
  1863.     begin
  1864.       for t:=0 to Source.Count-1 do
  1865.       begin
  1866.         tmpX:=NotMandatorySource[t];
  1867.         tmpY:=CalculateMany(ParentSeries.FDataSources,t);
  1868.         if not YMandatorySource then SwapDouble(tmpX,tmpY);
  1869.         ParentSeries.AddXY( tmpX,tmpY,Source.XLabel[t]{$IFNDEF D4},clTeeColor{$ENDIF});
  1870.       end;
  1871.     end;
  1872.  
  1873. begin
  1874.   if Source<>nil then
  1875.   With ParentSeries do
  1876.   begin
  1877.     YMandatorySource:=Source.YMandatory;
  1878.     if YMandatorySource then NotMandatorySource:=Source.XValues
  1879.                         else NotMandatorySource:=Source.YValues;
  1880.     if FDataSources.Count>1 then
  1881.        CalculateFunctionMany
  1882.     else
  1883.     if Source.Count>0 then
  1884.        if FunctionType.MovingFunction then CalculateMovingFunction
  1885.        else
  1886.        if FPeriod=0 then CalculateAllPoints(Source,NotMandatorySource)
  1887.                     else CalculateByPeriod(Source,NotMandatorySource);
  1888.   end;
  1889. end;
  1890.  
  1891. Procedure TTeeFunction.SetParentSeries(AParent:TChartSeries);
  1892. begin
  1893.   if AParent<>FParent then
  1894.   begin
  1895.     if Assigned(FParent) then FParent.FTeeFunction:=nil;
  1896.     AParent.SetFunction(Self);
  1897.   end;
  1898. end;
  1899.  
  1900. Function TTeeFunction.CalculateMany(SeriesList:TList; ValueIndex:Longint):Double;
  1901. begin
  1902.   result:=0;
  1903. end;
  1904.  
  1905. Procedure TTeeFunction.Assign(Source:TPersistent);
  1906. begin
  1907.   if Source is TTeeFunction then
  1908.   With TTeeFunction(Source) do
  1909.   begin
  1910.     Self.FPeriod     :=FPeriod;
  1911.     Self.FPeriodStyle:=FPeriodStyle;
  1912.     Self.FPeriodAlign:=FPeriodAlign;
  1913.   end;
  1914. end;
  1915.  
  1916. Procedure TTeeFunction.InternalSetPeriod(Const APeriod:Double);
  1917. begin
  1918.   FPeriod:=APeriod;
  1919. end;
  1920.  
  1921. Procedure TTeeFunction.SetPeriod(Const Value:Double);
  1922. begin
  1923.   if Value<0 then Raise Exception.Create(TeeMsg_FunctionPeriod);
  1924.   if FPeriod<>Value then
  1925.   begin
  1926.     FPeriod:=Value;
  1927.     Recalculate;
  1928.   end;
  1929. end;
  1930.  
  1931. Procedure TTeeFunction.SetPeriodAlign(Value:TFunctionPeriodalign);
  1932. begin
  1933.   if Value<>FPeriodAlign then
  1934.   begin
  1935.     FPeriodAlign:=Value;
  1936.     Recalculate;
  1937.   end;
  1938. end;
  1939.  
  1940. Procedure TTeeFunction.SetPeriodStyle(Value:TFunctionPeriodStyle);
  1941. begin
  1942.   if Value<>FPeriodStyle then
  1943.   begin
  1944.     FPeriodStyle:=Value;
  1945.     Recalculate;
  1946.   end;
  1947. end;
  1948.  
  1949. {$IFDEF D1}
  1950. procedure TTeeFunction.ReadState(Reader: TReader);
  1951. begin
  1952.   inherited ReadState(Reader);
  1953.   if Reader.Parent is TChartSeries then
  1954.      ParentSeries:=TChartSeries(Reader.Parent);
  1955. end;
  1956. {$ELSE}
  1957. function TTeeFunction.GetParentComponent: TComponent;
  1958. begin
  1959.   result:=FParent;
  1960. end;
  1961.  
  1962. procedure TTeeFunction.SetParentComponent(Value: TComponent);
  1963. begin
  1964.   if Assigned(Value) then ParentSeries:=TChartSeries(Value);
  1965. end;
  1966. {$ENDIF}
  1967.  
  1968. function TTeeFunction.HasParent: Boolean;
  1969. begin
  1970.   result:=True;
  1971. end;
  1972.  
  1973. { TChartValueLists }
  1974. Function TChartValueLists.GetValueList(Index:Integer):TChartValueList;
  1975. begin
  1976.   result:=TChartValueList(inherited Items[Index]);
  1977. end;
  1978.  
  1979. { TChartSeries }
  1980. Constructor TChartSeries.Create(AOwner: TComponent);
  1981. begin
  1982.   inherited Create(AOwner);
  1983.   FZOrder:=TeeAutoZOrder;
  1984.   IZOrder:=0;
  1985.   FActive:=True;
  1986.   FHorizAxis:=aBottomAxis;
  1987.   FGetHorizAxis:=nil;
  1988.   FVertAxis:=aLeftAxis;
  1989.   FGetVertAxis:=nil;
  1990.   FValuesList:=TChartValueLists.Create;
  1991.   FX:=TChartValueList.Create(Self,TeeMsg_ValuesX);
  1992.   FX.FDateTime:=False; { It was "True" in 1.03 version }
  1993.   FX.FOrder:=loAscending;
  1994.   FY:=TChartValueList.Create(Self,TeeMsg_ValuesY);
  1995.   FColors :=TList.Create;
  1996.   FXLabels:=TList.Create;
  1997.   FColor  :=clTeeColor;
  1998.   FShowInLegend:=True;
  1999.   FCursor:=crDefault;
  2000.   FMarks :=TSeriesMarks.Create(Self);
  2001.   FValueFormat    :=TeeMsg_DefValueFormat;
  2002.   FPercentFormat  :=TeeMsg_DefPercentFormat;
  2003.   FDataSources    :=TList.Create;
  2004.   FTempDataSources:=nil;
  2005.   FLinkedSeries:=TList.Create;
  2006.   FRecalcOptions := [rOnDelete,rOnModify,rOnInsert,rOnClear];
  2007.   FFirstVisibleIndex:=-1;
  2008.   FLastVisibleIndex :=-1;
  2009.   AllowSinglePoint:=True;
  2010.   CalcVisiblePoints:=True;
  2011.   HasZValues:=False;
  2012.   {$IFDEF D3}
  2013.   FIdentifier:='';
  2014.   FStyle:=[];
  2015.   {$ENDIF}
  2016. end;
  2017.  
  2018. {$IFDEF D1}
  2019. procedure TChartSeries.ReadState(Reader: TReader);
  2020. begin
  2021.   inherited ReadState(Reader);
  2022.   if Reader.Parent is TCustomAxisPanel then
  2023.      ParentChart := TCustomAxisPanel(Reader.Parent);
  2024. end;
  2025.  
  2026. Procedure TChartSeries.WriteComponents(Writer:TWriter);
  2027. begin
  2028.   if FunctionType<>nil then Writer.WriteComponent(FunctionType);
  2029.   inherited WriteComponents(Writer);
  2030. end;
  2031. {$ELSE}
  2032. Procedure TChartSeries.GetChildren( Proc:TGetChildProc
  2033.                                     {$IFDEF D3}; Root:TComponent {$ENDIF} );
  2034. begin
  2035.   inherited GetChildren(Proc{$IFDEF D3},Root{$ENDIF});
  2036.   if FunctionType<>nil then Proc(FunctionType);
  2037. end;
  2038.  
  2039. function TChartSeries.GetParentComponent: TComponent;
  2040. begin
  2041.   result:=FParent;
  2042. end;
  2043.  
  2044. procedure TChartSeries.SetParentComponent(AParent: TComponent);
  2045. begin
  2046.   if AParent is TCustomAxisPanel then ParentChart:=TCustomAxisPanel(AParent);
  2047. end;
  2048. {$ENDIF}
  2049.  
  2050. function TChartSeries.HasParent: Boolean;
  2051. begin
  2052.   result:=True;
  2053. end;
  2054.  
  2055. procedure TChartSeries.SetFunction(AFunction:TTeeFunction);
  2056. begin
  2057.   FTeeFunction.Free;
  2058.   FTeeFunction:=AFunction;
  2059.   if Assigned(FTeeFunction) then FTeeFunction.FParent:=Self;
  2060.   CheckDataSource;
  2061. end;
  2062.  
  2063. procedure TChartSeries.Notification( AComponent: TComponent;
  2064.                                      Operation: TOperation);
  2065. var tmp : TComponent;
  2066. begin
  2067.   inherited Notification(AComponent, Operation);
  2068.   if Operation=opRemove then
  2069.   begin
  2070.     tmp:=DataSource;
  2071.     if Assigned(tmp) and (AComponent=tmp) then SetDataSource(nil);
  2072.   end;
  2073. end;
  2074.  
  2075. procedure TChartSeries.DefineProperties(Filer: TFiler);
  2076. begin
  2077.   inherited DefineProperties(Filer);
  2078.   Filer.DefineProperty('DataSources',ReadData,WriteData,FDataSources.Count > 1);  { <-- don't translate }
  2079.   {$IFDEF D3}
  2080.   Filer.DefineProperty('Identifier',ReadIdentifier,WriteIdentifier,Identifier<>'');  { <-- don't translate }
  2081.   Filer.DefineProperty('Style',ReadStyle,WriteStyle,Style<>[]);  { <-- don't translate }
  2082.   {$ENDIF}
  2083. end;
  2084.  
  2085. {$IFDEF D3}
  2086. procedure TChartSeries.ReadIdentifier(Reader: TReader);
  2087. begin
  2088.   Identifier:=Reader.ReadString;
  2089. end;
  2090.  
  2091. procedure TChartSeries.WriteIdentifier(Writer: TWriter);
  2092. begin
  2093.   Writer.WriteString(Identifier);
  2094. end;
  2095.  
  2096. procedure TChartSeries.ReadStyle(Reader: TReader);
  2097. var tmp : Integer;
  2098. begin
  2099.   tmp:=Reader.ReadInteger;
  2100.   FStyle:=[];
  2101.   if (tmp and 1)=1 then FStyle:=FStyle+[tssIsTemplate];
  2102.   if (tmp and 2)=2 then FStyle:=FStyle+[tssDenyChangeType];
  2103.   if (tmp and 4)=4 then FStyle:=FStyle+[tssDenyDelete];
  2104.   if (tmp and 8)=8 then FStyle:=FStyle+[tssDenyClone];
  2105.   if (tmp and 16)=16 then FStyle:=FStyle+[tssIsPersistent];
  2106.   if (tmp and 32)=32 then FStyle:=FStyle+[tssHideDataSource];
  2107. end;
  2108.  
  2109. procedure TChartSeries.WriteStyle(Writer: TWriter);
  2110. var tmp : Integer;
  2111. begin
  2112.   tmp:=0;
  2113.   if tssIsTemplate     in FStyle then Inc(tmp);
  2114.   if tssDenyChangeType in FStyle then Inc(tmp,2);
  2115.   if tssDenyDelete     in FStyle then Inc(tmp,4);
  2116.   if tssDenyClone      in FStyle then Inc(tmp,8);
  2117.   if tssIsPersistent   in FStyle then Inc(tmp,16);
  2118.   if tssHideDataSource in FStyle then Inc(tmp,32);
  2119.   Writer.WriteInteger(tmp);
  2120. end;
  2121. {$ENDIF}
  2122.  
  2123. procedure TChartSeries.ReadData(Reader: TReader);
  2124. begin
  2125.   Reader.ReadListBegin;
  2126.   FTempDataSources:=TStringList.Create;
  2127.   With FTempDataSources do
  2128.   begin
  2129.     Clear;
  2130.     while not Reader.EndOfList do Add(Reader.ReadString);
  2131.   end;
  2132.   Reader.ReadListEnd;
  2133. end;
  2134.  
  2135. procedure TChartSeries.WriteData(Writer: TWriter);
  2136. var t : Longint;
  2137. begin
  2138.   With Writer do
  2139.   begin
  2140.     WriteListBegin;
  2141.     With FDataSources do
  2142.          for t:=0 to Count-1 do WriteString(TComponent(Items[t]).Name);
  2143.     WriteListEnd;
  2144.   end;
  2145. end;
  2146.  
  2147. Function TChartSeries.YMandatory:Boolean;
  2148. begin
  2149.   result:=MandatoryValueList=YValues;
  2150. end;
  2151.  
  2152. Function TChartSeries.MandatoryValueList:TChartValueList; { virtual }
  2153. Begin
  2154.   result:=YValues;
  2155. end;
  2156.  
  2157. Function TChartSeries.DrawValuesForward:Boolean;
  2158. begin
  2159.   result:=True;
  2160. end;
  2161.  
  2162. Function TChartSeries.DrawSeriesForward(ValueIndex:Longint):Boolean;
  2163. begin
  2164.   result:=True;
  2165. end;
  2166.  
  2167. procedure TChartSeries.DrawAllValues;
  2168. Var t : Longint;
  2169. Begin
  2170.   if DrawValuesForward then
  2171.      for t:=FFirstVisibleIndex to FLastVisibleIndex do DrawValue(t)
  2172.   else
  2173.      for t:=FLastVisibleIndex downto FFirstVisibleIndex do DrawValue(t);
  2174. End;
  2175.  
  2176. Function TChartSeries.SameClass(tmpSeries:TChartSeries):Boolean;
  2177. begin
  2178.   result:=( (Self is tmpSeries.ClassType) or (tmpSeries is Self.ClassType));
  2179. end;
  2180.  
  2181. Function TChartSeries.PointOrigin(ValueIndex:Longint; SumAll:Boolean):Double;
  2182. var t         : Longint;
  2183.     tmpSeries : TChartSeries;
  2184. Begin
  2185.   result:=0;
  2186.   if Assigned(FParent) then
  2187.   with FParent do
  2188.   for t:=0 to FSeriesList.Count-1 do
  2189.   Begin
  2190.     tmpSeries:=Series[t];
  2191.     if (not SumAll) and (tmpSeries=Self) then Break
  2192.     else
  2193.     With tmpSeries do
  2194.     if Active and SameClass(Self) and (Count>ValueIndex) then
  2195.        result:=result+GetOriginValue(ValueIndex);
  2196.   end;
  2197. end;
  2198.  
  2199. Function TChartSeries.CreateChartPen:TChartPen;
  2200. begin
  2201.   result:=TChartPen.Create(CanvasChanged);
  2202. end;
  2203.  
  2204. Procedure TChartSeries.CheckDataSource;
  2205. begin
  2206.   if Assigned(FParent) then FParent.CheckDataSource(Self);
  2207. end;
  2208.  
  2209. procedure TChartSeries.SetRecalcOptions(Value: TSeriesRecalcOptions);
  2210. begin
  2211.   FRecalcOptions:=Value;
  2212. end;
  2213.  
  2214. Procedure TChartSeries.SetColorSource(Const Value:String);
  2215. Begin
  2216.   if FColorSource<>Value then
  2217.   Begin
  2218.     FColorSource:=Value;
  2219.     if Assigned(FParent) then FParent.CheckDataSource(Self);
  2220.   end;
  2221. end;
  2222.  
  2223. Procedure TChartSeries.SetLabelsSource(Const Value:String);
  2224. Begin
  2225.   if FLabelsSource<>Value then
  2226.   Begin
  2227.     FLabelsSource:=Value;
  2228.     if Assigned(FParent) then FParent.CheckDataSource(Self);
  2229.   end;
  2230. end;
  2231.  
  2232. Function TChartSeries.GetCursorValueIndex:Longint;
  2233. Var Mouse : TPoint;
  2234. Begin
  2235.   Mouse:=ParentChart.GetCursorPos;
  2236.   result:=Clicked(Mouse.X,Mouse.Y);
  2237. end;
  2238.  
  2239. Procedure TChartSeries.GetCursorValues(Var x,y:Double);
  2240. Var Mouse : TPoint;
  2241. Begin
  2242.   Mouse:=ParentChart.GetCursorPos;
  2243.   x:=XScreenToValue(Mouse.X);
  2244.   y:=YScreenToValue(Mouse.Y);
  2245. end;
  2246.  
  2247. Function TChartSeries.GetDataSource:TComponent;
  2248. begin
  2249.   if Assigned(FDataSources) and (FDataSources.Count>0) then
  2250.      result:=FDataSources[0]
  2251.   else
  2252.      result:=nil;
  2253. end;
  2254.  
  2255. Procedure TChartSeries.InternalAddDataSource(Value:TComponent);
  2256. begin
  2257.   if Assigned(Value) then
  2258.   begin
  2259.     FDataSources.Add(Value);
  2260.     if Value is TChartSeries then
  2261.        TChartSeries(Value).AddLinkedSeries(Self)
  2262.     {$IFNDEF D1}
  2263.     else
  2264.        Value.FreeNotification(Self)
  2265.     {$ENDIF}
  2266.     ;
  2267.   end;
  2268. end;
  2269.  
  2270. Procedure TChartSeries.RemoveAllLinkedSeries;
  2271. var t : Integer;
  2272. begin
  2273.   if Assigned(FDataSources) then
  2274.      for t:=0 to FDataSources.Count-1 do
  2275.      if (FDataSources[t]<>nil) and (TComponent(FDataSources[t]) is TChartSeries) then
  2276.         TChartSeries(FDataSources[t]).RemoveLinkedSeries(Self);
  2277. end;
  2278.  
  2279. Procedure TChartSeries.SetDataSource(Value:TComponent);
  2280.  
  2281.   Procedure ClearDataSources;
  2282.   begin
  2283.     RemoveAllLinkedSeries;
  2284.     FDataSources.Clear;
  2285.   end;
  2286.  
  2287.   Procedure InternalRemoveDataSource;
  2288.   Begin
  2289.     if Assigned(FParent) and
  2290.        (DataSource<>nil) then
  2291.          FParent.RemovedDataSource(Self,DataSource);
  2292.     ClearDataSources;
  2293.     if Assigned(FParent) and
  2294.        (csDesigning in FParent.ComponentState) then
  2295.        FillSampleValues(NumSampleValues)
  2296.     else
  2297.        Clear;
  2298.     Repaint;
  2299.   end;
  2300.  
  2301.   Procedure InternalSetDataSource;
  2302.   Begin
  2303.     if not Assigned(FParent) then
  2304.        raise ChartException.Create(TeeMsg_SeriesSetDataSource)
  2305.     else
  2306.     if FParent.IsValidDataSource(Self,Value) then
  2307.     Begin
  2308.       if FDataSources.IndexOf(Value)=-1 then
  2309.       begin
  2310.         if Value is TChartSeries then CheckOtherSeries(TChartSeries(Value));
  2311.         if not (csLoading in ComponentState) then ClearDataSources;
  2312.  
  2313.         InternalAddDataSource(Value);
  2314.         if not (csLoading in ComponentState) then FParent.CheckDataSource(Self);
  2315.       end;
  2316.     end
  2317.     else
  2318.       Raise ChartException.CreateFmt(TeeMsg_SeriesInvDataSource,[Value.Name]);
  2319.   end;
  2320.  
  2321. Begin
  2322.   if not Assigned(Value) then InternalRemoveDataSource
  2323.                          else InternalSetDataSource;
  2324. end;
  2325.  
  2326. Function TChartSeries.IsValidSourceOf(Value:TChartSeries):Boolean;
  2327. Begin
  2328.   result:=Value<>Self;
  2329. end;
  2330.  
  2331. Function TChartSeries.IsValidSeriesSource(Value:TChartSeries):Boolean;
  2332. Begin
  2333.   result:=True; { abstract }
  2334. end;
  2335.  
  2336. Procedure TChartSeries.CanvasChanged(Sender:TObject);
  2337. Begin
  2338.   Repaint;
  2339. end;
  2340.  
  2341. Function TChartSeries.GetYValueList(AListName:String):TChartValueList;
  2342. Var t : Integer;
  2343. Begin
  2344.   result:=FY;
  2345.   AListName:=AnsiUppercase(AListName);
  2346.   With FValuesList do
  2347.   for t:=2 to Count-1 do
  2348.   if AListName=AnsiUpperCase(ValueList[t].Name) then
  2349.   Begin
  2350.     result:=ValueList[t];
  2351.     exit;
  2352.   end;
  2353. end;
  2354.  
  2355. Procedure TChartSeries.CheckOtherSeries(Source:TChartSeries);
  2356. Begin
  2357.   if Assigned(FParent) then FParent.CheckOtherSeries(Self,Source);
  2358. end;
  2359.  
  2360. Procedure TChartSeries.ColorRange( AValueList:TChartValueList;
  2361.                                    Const FromValue,ToValue:Double; AColor:TColor);
  2362. var t        : Longint;
  2363.     tmpValue : Double;
  2364. begin
  2365.   for t:=0 to AValueList.FList.Count-1 do
  2366.   Begin
  2367.     tmpValue:=AValueList.GetValue(t);
  2368.     if (tmpValue>=FromValue) and (tmpValue<=ToValue) then
  2369.        FColors[t]:=Pointer(AColor);
  2370.   end;
  2371.   Repaint;
  2372. end;
  2373.  
  2374. Function TChartSeries.Clicked(x,y:Integer):Longint;
  2375. begin
  2376.   Result:=-1; { abstract, no point clicked }
  2377. end;
  2378.  
  2379. Procedure TChartSeries.RecalcGetAxis;
  2380. Begin
  2381.   if Assigned(FParent) then
  2382.   begin
  2383.     FGetHorizAxis:=FParent.FBottomAxis;
  2384.     Case FHorizAxis of
  2385.       aTopAxis        : FGetHorizAxis:=FParent.FTopAxis;
  2386.       aCustomHorizAxis: if Assigned(FCustomHorizAxis) then FGetHorizAxis:=FCustomHorizAxis;
  2387.     end;
  2388.     FGetVertAxis:=FParent.FLeftAxis;
  2389.     Case FVertAxis of
  2390.       aRightAxis     : FGetVertAxis:=FParent.FRightAxis;
  2391.       aCustomVertAxis: if Assigned(FCustomVertAxis) then FGetVertAxis:=FCustomVertAxis;
  2392.     end;
  2393.   end
  2394.   else
  2395.   begin
  2396.     FGetHorizAxis:=nil;
  2397.     FGetVertAxis:=nil;
  2398.   end;
  2399. end;
  2400.  
  2401. Procedure TChartSeries.SetHorizAxis(Value:THorizAxis);
  2402. Begin
  2403.   if FHorizAxis<>Value then
  2404.   begin
  2405.     FHorizAxis:=Value;
  2406.     RecalcGetAxis;
  2407.     Repaint;
  2408.   end;
  2409. end;
  2410.  
  2411. Procedure TChartSeries.SetVertAxis(Value:TVertAxis);
  2412. Begin
  2413.   if FVertAxis<>Value then
  2414.   begin
  2415.     FVertAxis:=Value;
  2416.     RecalcGetAxis;
  2417.     Repaint;
  2418.   end;
  2419. end;
  2420.  
  2421. Procedure TChartSeries.SetChartValueList( Var AValueList:TChartValueList;
  2422.                                           Value:TChartValueList);
  2423. Begin
  2424.   AValueList.Assign(Value);
  2425.   Repaint;
  2426. end;
  2427.  
  2428. Procedure TChartSeries.SetXValues(Value:TChartValueList);
  2429. Begin
  2430.   SetChartValueList(FX,Value);
  2431. end;
  2432.  
  2433. Procedure TChartSeries.SetYValues(Value:TChartValueList);
  2434. Begin
  2435.   SetChartValueList(FY,Value);
  2436. end;
  2437.  
  2438. Procedure TChartSeries.SetTitle(Value:String);
  2439. Begin
  2440.   SetStringProperty(FTitle,Value);
  2441. end;
  2442.  
  2443. Function TChartSeries.GetValue(IsX:Boolean; ValueIndex:Longint):Double;
  2444. begin
  2445.   if IsX then result:=GetxValue(ValueIndex)
  2446.          else result:=GetyValue(ValueIndex);  { <-- lowercase, conflict with BCB }
  2447. end;
  2448.  
  2449. Procedure TChartSeries.CalcFirstLastVisibleIndex;
  2450.  
  2451.   Function CalcMinMaxValue(A,B,C,D:Integer):Double;
  2452.   begin
  2453.     if YMandatory then
  2454.     With GetHorizAxis do
  2455.          if Inverted then result:=CalcPosPoint(C)
  2456.                      else result:=CalcPosPoint(A)
  2457.     else
  2458.     With GetVertAxis do
  2459.          if Inverted then result:=CalcPosPoint(B)
  2460.                      else result:=CalcPosPoint(D);
  2461.   end;
  2462.  
  2463. Var tmpMin           : Double;
  2464.     tmpMax           : Double;
  2465.     NotMandatory     : TChartValueList;
  2466.     tmpLastIndex     : Longint;
  2467.     OrderedPoints    : Boolean;
  2468. Begin
  2469.   FFirstVisibleIndex:=-1;
  2470.   FLastVisibleIndex:=-1;
  2471.   if Count>0 then
  2472.   Begin
  2473.     tmpLastIndex:=Count-1;
  2474.     if YMandatory then OrderedPoints:=XValues.Order<>loNone
  2475.                   else OrderedPoints:=YValues.Order<>loNone;
  2476.  
  2477.     if CalcVisiblePoints and OrderedPoints then
  2478.     begin
  2479.       FFirstVisibleIndex:=0;
  2480.  
  2481.       With ParentChart.ChartRect do
  2482.            tmpMin:=CalcMinMaxValue(Left,Top,Right,Bottom);
  2483.  
  2484.       if YMandatory then NotMandatory:=XValues
  2485.                     else NotMandatory:=YValues;
  2486.  
  2487.       While NotMandatory.GetValue(FFirstVisibleIndex)<tmpMin do
  2488.       Begin
  2489.         inc(FFirstVisibleIndex);
  2490.         if FFirstVisibleIndex>tmpLastIndex then
  2491.         begin
  2492.           FFirstVisibleIndex:=-1;
  2493.           break;
  2494.         end;
  2495.       end;
  2496.       if FFirstVisibleIndex>=0 then
  2497.       Begin
  2498.         With ParentChart.ChartRect do
  2499.              tmpMax:=CalcMinMaxValue(Right,Bottom,Left,Top);
  2500.  
  2501.         if NotMandatory.Last<=tmpMax then FLastVisibleIndex:=tmpLastIndex
  2502.         else
  2503.         Begin
  2504.           FLastVisibleIndex:=FFirstVisibleIndex;
  2505.           While NotMandatory.GetValue(FLastVisibleIndex)<tmpMax do
  2506.           begin
  2507.             inc(FLastVisibleIndex);
  2508.             if FLastVisibleIndex>tmpLastIndex then
  2509.             begin
  2510.               FLastVisibleIndex:=tmpLastIndex;
  2511.               break;
  2512.             end;
  2513.           end;
  2514.           if (not DrawBetweenPoints) and
  2515.              (NotMandatory.GetValue(FLastVisibleIndex)>tmpMax) then
  2516.                 Dec(FLastVisibleIndex);
  2517.         end;
  2518.       end;
  2519.     end
  2520.     else
  2521.     begin
  2522.       FFirstVisibleIndex:=0;
  2523.       FLastVisibleIndex:=tmpLastIndex;
  2524.     end;
  2525.   end;
  2526. end;
  2527.  
  2528. Procedure TChartSeries.Repaint;
  2529. Begin
  2530.   if Assigned(FParent) then FParent.Invalidate;
  2531. end;
  2532.  
  2533. procedure TChartSeries.DrawValue(ValueIndex:Longint);
  2534. begin { nothing }
  2535. end;
  2536.  
  2537. Procedure TChartSeries.SetActive(Value:Boolean);
  2538. Begin
  2539.   SetBooleanProperty(FActive,Value);
  2540. end;
  2541.  
  2542. Function TChartSeries.IsValueFormatStored:Boolean;
  2543. Begin
  2544.   result:=FValueFormat<>TeeMsg_DefValueFormat;
  2545. end;
  2546.  
  2547. Function TChartSeries.IsPercentFormatStored:Boolean;
  2548. Begin
  2549.   result:=FPercentFormat<>TeeMsg_DefPercentFormat;
  2550. end;
  2551.  
  2552. Procedure TChartSeries.DeletedValue(Source:TChartSeries; ValueIndex:Longint);
  2553. Begin
  2554.   Delete(ValueIndex);
  2555. end;
  2556.  
  2557. Procedure TChartSeries.AddValue(ValueIndex:Longint);
  2558. var t : Integer;
  2559. Begin
  2560.   With FValuesList do
  2561.   for t:=2 to Count-1 do
  2562.       With ValueList[t] do InsertChartValue(ValueIndex,TempValue);
  2563. end;
  2564.  
  2565. Function TChartSeries.AddChartValue(Source:TChartSeries; ValueIndex:Longint):Longint;
  2566. var t    : Longint;
  2567.     tmpX : Double;
  2568.     tmpY : Double;
  2569. begin
  2570.   With Source do
  2571.   begin
  2572.     tmpX:=FX.GetValue(ValueIndex);
  2573.     tmpY:=FY.GetValue(ValueIndex);
  2574.   end;
  2575.   { if we are adding values from an Horizontal Bar series... }
  2576.   if Self.YMandatory<>Source.YMandatory then SwapDouble(tmpX,tmpY);
  2577.   { pending: if ...FY.Order<>loNone then (inverted) }
  2578.   result:=FX.AddChartValue(tmpX);
  2579.   FY.InsertChartValue(result,tmpY);
  2580.   { rest of lists... }
  2581.   With FValuesList do
  2582.   for t:=2 to Count-1 do
  2583.       ValueList[t].InsertChartValue(result,Source.FValuesList.ValueList[t].Value[ValueIndex]);
  2584. end;
  2585.  
  2586. Procedure TChartSeries.AddedValue(Source:TChartSeries; ValueIndex:Longint);
  2587. Var tmpIndex : Longint;
  2588. Begin
  2589.   tmpIndex:=AddChartValue(Source,ValueIndex);
  2590.   if Source.FColors.Count>ValueIndex then FColors.Insert(tmpIndex,Source.FColors[ValueIndex]);
  2591.   if Source.FXLabels.Count>ValueIndex then InsertLabel(tmpIndex,Source.GetXLabel(ValueIndex));
  2592.   NotifyNewValue(Self,tmpIndex);
  2593. end;
  2594.  
  2595. Function TChartSeries.LegendToValueIndex(LegendIndex:Integer):Integer;
  2596. begin
  2597.   result:=LegendIndex;
  2598. end;
  2599.  
  2600. Function TChartSeries.LegendString( LegendIndex:Integer;
  2601.                                     LegendTextStyle:TLegendTextStyle ):String;
  2602. Var tmpValue        : Double;
  2603.     tmpPercentValue : Double;
  2604.     tmpAxis         : TChartAxis;
  2605.     tmpSt           : String;
  2606.     tmpPercentSt    : String;
  2607.     ValueIndex      : Integer;
  2608. begin
  2609.   ValueIndex:=LegendToValueIndex(LegendIndex);
  2610.   result:=XLabel[ValueIndex];
  2611.   if LegendTextStyle<>ltsPlain then
  2612.   begin
  2613.     tmpValue:=GetMarkValue(ValueIndex);
  2614.     tmpSt:=FormatFloat(ValueFormat,tmpValue);
  2615.     if (LegendTextStyle=ltsLeftPercent) or (LegendTextStyle=ltsRightPercent) then
  2616.     With MandatoryValueList do
  2617.     begin
  2618.       if TotalAbs=0 then tmpPercentValue:=100
  2619.                     else tmpPercentValue:=100.0*tmpValue/TotalAbs;
  2620.       tmpPercentSt:=FormatFloat(PercentFormat,tmpPercentValue);
  2621.     end;
  2622.     Case LegendTextStyle of
  2623.       ltsLeftValue   : result:=tmpSt+' '+result;
  2624.       ltsRightValue  : result:=result+' '+tmpSt;
  2625.       ltsLeftPercent : result:=tmpPercentSt+' '+result;
  2626.       ltsRightPercent: result:=result+' '+tmpPercentSt;
  2627.       ltsXValue      : begin
  2628.                          tmpAxis:=GetHorizAxis;
  2629.                          if tmpAxis=nil then
  2630.                             result:=FormatFloat(ValueFormat,XValue[ValueIndex])
  2631.                          else
  2632.                             result:=tmpAxis.LabelValue(XValue[ValueIndex]);
  2633.                        end;
  2634.     end;
  2635.   end;
  2636. end;
  2637.  
  2638. Procedure TChartSeries.AddValues(Source:TChartSeries);
  2639. var t : Longint;
  2640. Begin
  2641.   if IsValidSourceOf(Source) then
  2642.   begin
  2643.     Clear;
  2644.     if FunctionType=nil then { copy values... }
  2645.        for t:=0 to Source.Count-1 do AddedValue(Source,t)
  2646.     else
  2647.     begin
  2648.       XValues.DateTime:=Source.XValues.DateTime;
  2649.       YValues.DateTime:=Source.YValues.DateTime;
  2650.       FunctionType.AddPoints(Source); { calculate function }
  2651.     end;
  2652.     RefreshSeries; { propagate changes... }
  2653.   end;
  2654. end;
  2655.  
  2656. Procedure TChartSeries.AssignValues(Source:TChartSeries);
  2657. Begin
  2658.   AddValues(Source);
  2659. End;
  2660.  
  2661. Procedure TChartSeries.RefreshSeries;
  2662. Begin
  2663.   NotifyValue(veRefresh,0);
  2664. End;
  2665.  
  2666. Function TChartSeries.GetEditorClass:String;
  2667. Begin
  2668.   result:='';
  2669. end;
  2670.  
  2671. Function TChartSeries.MoreSameZOrder:Boolean;
  2672. Var tmpSeries : TChartSeries;
  2673.     t         : Longint;
  2674. Begin
  2675.   for t:=0 to FParent.FSeriesList.Count-1 do
  2676.   Begin
  2677.     tmpSeries:=FParent.Series[t];
  2678.     if tmpSeries<>Self then
  2679.     With tmpSeries do
  2680.     if FActive and (not HasZValues) and (ZOrder=Self.ZOrder) then
  2681.     Begin
  2682.       result:=True;
  2683.       exit;
  2684.     end;
  2685.   end;
  2686.   result:=False;
  2687. End;
  2688.  
  2689. Function TChartSeries.FirstInZOrder:Boolean;
  2690. Var tmpSeries : TChartSeries;
  2691.     t         : Longint;
  2692. Begin
  2693.   if FActive then
  2694.   begin
  2695.     result:=True;
  2696.     for t:=0 to FParent.FSeriesList.Count-1 do
  2697.     Begin
  2698.      tmpSeries:=FParent.Series[t];
  2699.      if tmpSeries=Self then break
  2700.      else
  2701.        With tmpSeries do
  2702.        if FActive and (ZOrder=Self.ZOrder) then
  2703.        Begin
  2704.          result:=False;
  2705.          break;
  2706.        end;
  2707.     end;
  2708.   end
  2709.   else result:=False;
  2710. end;
  2711.  
  2712. procedure TChartSeries.DoBeforeDrawChart;
  2713. begin
  2714. end;
  2715.  
  2716. procedure TChartSeries.DoBeforeDrawValues;
  2717. Begin
  2718.   if Assigned(FBeforeDrawValues) then FBeforeDrawValues(Self);
  2719. end;
  2720.  
  2721. procedure TChartSeries.DoAfterDrawValues;
  2722. Begin
  2723.   if Assigned(FAfterDrawValues) then FAfterDrawValues(Self);
  2724. end;
  2725.  
  2726. procedure TChartSeries.DrawMarks;
  2727. Var t                   : Longint;
  2728.     St                  : String;
  2729.     tmpDoubleFrameWidth : Integer;
  2730.     tmpW,tmpH           : Integer;
  2731.     APosition           : TSeriesMarkPosition;
  2732. Begin
  2733.   With FParent,FMarks do
  2734.   begin
  2735.     APosition:=TSeriesMarkPosition.Create;
  2736.     for t:=FFirstVisibleIndex to FLastVisibleIndex do
  2737.     if ValueColor[t]<>clNone then
  2738.     Begin
  2739.       St:=GetMarkText(t);
  2740.       if St<>'' then
  2741.       Begin
  2742.         FontCanvas(FFont);
  2743.         if View3D and View3Doptions.ZoomText then
  2744.         With Canvas.Font do
  2745.           Size:=MaxLong(1,Round(0.01*View3DOptions.Zoom*Size));
  2746.  
  2747.         tmpW:=MultiLineTextWidth(St,tmpH)+Canvas.TextWidth(TeeCharForHeight);
  2748.         tmpH:=tmpH*Canvas.FontHeight;
  2749.  
  2750.         Canvas.AssignVisiblePen(FFrame);
  2751.         if FFrame.Visible then
  2752.         Begin
  2753.           tmpDoubleFrameWidth:=2*FFrame.Width;
  2754.           Inc(tmpW,tmpDoubleFrameWidth);
  2755.           Inc(tmpH,tmpDoubleFrameWidth);
  2756.         end;
  2757.  
  2758.         With APosition do
  2759.         begin
  2760.           Width:=tmpW;
  2761.           Height:=tmpH;
  2762.           ArrowTo.X:=CalcXPos(t);
  2763.           ArrowTo.Y:=CalcYPos(t);
  2764.           ArrowFrom:=ArrowTo;
  2765.           LeftTop.X:=ArrowTo.X-(tmpW div 2);
  2766.           LeftTop.Y:=ArrowTo.Y-tmpH+1;
  2767.         end;
  2768.         DrawMark(t,St,APosition);
  2769.       end;
  2770.     end;
  2771.     APosition.Free;
  2772.   end;
  2773. end;
  2774.  
  2775. Procedure TChartSeries.CalcHorizMargins(Var LeftMargin,RightMargin:Integer);
  2776. begin
  2777.   LeftMargin:=0; RightMargin:=0;
  2778. end;
  2779.  
  2780. Procedure TChartSeries.CalcVerticalMargins(Var TopMargin,BottomMargin:Integer);
  2781. begin
  2782.   TopMargin:=0; BottomMargin:=0;
  2783. end;
  2784.  
  2785. Procedure TChartSeries.DrawMark( ValueIndex:Longint; Const St:String;
  2786.                                  APosition:TSeriesMarkPosition);
  2787. Begin
  2788.   FMarks.Draw(ValueIndex,ValueColor[ValueIndex],St,APosition);
  2789. end;
  2790.  
  2791. Procedure TChartSeries.SetIntegerProperty(Var Variable:Integer; Value:Integer);
  2792. Begin
  2793.   if Variable<>Value then
  2794.   begin
  2795.     Variable:=Value;   Repaint;
  2796.   end;
  2797. end;
  2798.  
  2799. Procedure TChartSeries.SetLongintProperty(Var Variable:Longint; Value:Longint);
  2800. Begin
  2801.   if Variable<>Value then
  2802.   begin
  2803.     Variable:=Value;   Repaint;
  2804.   end;
  2805. end;
  2806.  
  2807. Procedure TChartSeries.SetStringProperty(Var Variable:String; Const Value:String);
  2808. Begin
  2809.   if Variable<>Value then
  2810.   begin
  2811.     Variable:=Value;   Repaint;
  2812.   end;
  2813. end;
  2814.  
  2815. Procedure TChartSeries.SetBooleanProperty(Var Variable:Boolean; Value:Boolean);
  2816. Begin
  2817.   if Variable<>Value then
  2818.   begin
  2819.     Variable:=Value;   Repaint;
  2820.   end;
  2821. end;
  2822.  
  2823. Procedure TChartSeries.InsertLabel(ValueIndex:Longint; Const ALabel:String);
  2824. Begin
  2825.   FXLabels.Insert(ValueIndex,GetMemLabel(ALabel));
  2826. end;
  2827.  
  2828. Function TChartSeries.AddXY( Const AXValue,AYValue:Double;
  2829.                              Const ALabel:String; AColor:TColor):Longint;
  2830. Begin
  2831.   result:=-1;
  2832.   FX.TempValue:=AXValue;
  2833.   FY.TempValue:=AYValue;
  2834.   if (not Assigned(FOnBeforeAdd)) or FOnBeforeAdd(Self) then
  2835.   Begin
  2836.     result:=FX.AddChartValue(FX.TempValue);
  2837.     FY.InsertChartValue(result,FY.TempValue);
  2838.     {$IFDEF TEEOCX}
  2839.     if AColor=clDefault then AColor:=clTeeColor;  { patch for OCX }
  2840.     {$ENDIF}
  2841.     FColors.Insert(result,Pointer(AColor));
  2842.     InsertLabel(result,ALabel);
  2843.     NotifyNewValue(Self,result);
  2844.   end;
  2845. end;
  2846.  
  2847. Procedure TChartSeries.NotifyNewValue(Sender:TChartSeries; ValueIndex:Longint);
  2848. Begin
  2849.   if Assigned(FOnAfterAdd) then FOnAfterAdd(Sender,ValueIndex);
  2850.   NotifyValue(veAdd,ValueIndex);
  2851.   if FActive then Repaint;
  2852. end;
  2853.  
  2854. Function TChartSeries.IsNull(ValueIndex:Longint):Boolean;
  2855. begin
  2856.   result:=ValueColor[ValueIndex]=clNone;
  2857. end;
  2858.  
  2859. Function TChartSeries.AddNull(Const ALabel:String):Longint;
  2860. begin
  2861.   result:=Add( 0, ALabel, clNone );
  2862. end;
  2863.  
  2864. Function TChartSeries.AddNullXY(Const X,Y:Double; Const ALabel:String):Longint;
  2865. begin
  2866.   result:=AddXY(X,Y,ALabel,clNone );
  2867. end;
  2868.  
  2869. Function TChartSeries.AddArray(Const Values:array of Double):Longint;
  2870. var t : Longint;
  2871. begin
  2872.   result:=High(Values)-Low(Values)+1;
  2873.   for t:=Low(Values) to High(Values) do Add( Values[t], ''{$IFNDEF D4},clTeeColor{$ENDIF} );
  2874.   RefreshSeries;
  2875. end;
  2876.  
  2877. Function TChartSeries.Add(Const AValue:Double; Const ALabel:String; AColor:TColor):Longint;
  2878. Begin
  2879.   if YMandatory then result:=AddY( AValue, ALabel, AColor )
  2880.                 else result:=AddX( AValue, ALabel, AColor );
  2881. end;
  2882.  
  2883. Function TChartSeries.AddX(Const AXValue:Double; Const ALabel:String; AColor:TColor):Longint;
  2884. Begin
  2885.   result:=AddXY(AXValue,FX.Count,ALabel,AColor);
  2886. end;
  2887.  
  2888. Function TChartSeries.AddY(Const AYValue:Double; Const ALabel:String; AColor:TColor):Longint;
  2889. Begin
  2890.   result:=AddXY(FX.Count,AYValue,ALabel,AColor);
  2891. end;
  2892.  
  2893. Function TChartSeries.Count:Longint; { <-- Total number of points in the series }
  2894. Begin
  2895.   result:=FX.Count;
  2896. end;
  2897.  
  2898. Function TChartSeries.CountLegendItems:Integer;
  2899. begin
  2900.   result:=Count
  2901. end;
  2902.  
  2903. Function TChartSeries.VisibleCount:Longint;
  2904. Begin
  2905.   result:=FLastVisibleIndex-FFirstVisibleIndex+1;
  2906. end;
  2907.  
  2908. Function TChartSeries.MarkPercent(ValueIndex:Longint; AddTotal:Boolean):String;
  2909. var tmp : Double;
  2910. Begin
  2911.   With MandatoryValueList do
  2912.   Begin
  2913.     if TotalAbs<>0 then tmp:=100.0*Abs(GetMarkValue(ValueIndex))/TotalAbs
  2914.                    else tmp:=100;
  2915.     result:=FormatFloat(FPercentFormat,tmp);
  2916.     if AddTotal then
  2917.        FmtStr(result,TeeMsg_DefaultPercentOf,[result,FormatFloat(FValueFormat,TotalAbs)]);
  2918.   end;
  2919. end;
  2920.  
  2921. Function TChartSeries.GetOriginValue(ValueIndex:Longint):Double;
  2922. begin
  2923.   result:=GetMarkValue(ValueIndex);
  2924. end;
  2925.  
  2926. Function TChartSeries.GetMarkValue(ValueIndex:Longint):Double;
  2927. begin
  2928.   result:=MandatoryValueList[ValueIndex];
  2929. end;
  2930.  
  2931. Function TChartSeries.GetMarkText(ValueIndex:Longint):String;
  2932.  
  2933.   Function XLabelOrValue(ValueIndex:Longint):String;
  2934.   Begin
  2935.     result:=XLabel[ValueIndex];
  2936.     if result='' then result:=FormatFloat(FValueFormat,GetMarkValue(ValueIndex));
  2937.   End;
  2938.  
  2939. Begin
  2940.   With FMarks do
  2941.   Case FMarkerStyle of
  2942.     smsValue:        result:=FormatFloat(FValueFormat,GetMarkValue(ValueIndex));
  2943.     smsPercent:      result:=MarkPercent(ValueIndex,False);
  2944.     smsLabel:        result:=XLabelOrValue(ValueIndex);
  2945.     smsLabelPercent: result:=XLabelOrValue(ValueIndex)+' '+MarkPercent(ValueIndex,False);
  2946.     smsLabelValue:   result:=XLabelOrValue(ValueIndex)+' '+FormatFloat(FValueFormat,GetMarkValue(ValueIndex));
  2947.     smsLegend:       result:=ParentChart.FormattedValueLegend(Self,ValueIndex);
  2948.     smsPercentTotal: result:=MarkPercent(ValueIndex,True);
  2949.     smsLabelPercentTotal: result:=XLabelOrValue(ValueIndex)+' '+MarkPercent(ValueIndex,True);
  2950.     smsXValue:       if GetHorizAxis=nil then
  2951.                         result:=FormatFloat(FValueFormat,XValue[ValueIndex])
  2952.                      else
  2953.                         result:=GetHorizAxis.LabelValue(XValue[ValueIndex]);
  2954.   else
  2955.     result:='';
  2956.   end;
  2957.   if Assigned(FOnGetMarkText) then FOnGetMarkText(Self,ValueIndex,result);
  2958. end;
  2959.  
  2960. Procedure TChartSeries.SetValueFormat(Const Value:String);
  2961. Begin
  2962.   SetStringProperty(FValueFormat,Value);
  2963. end;
  2964.  
  2965. Procedure TChartSeries.SetPercentFormat(Const Value:String);
  2966. Begin
  2967.   SetStringProperty(FPercentFormat,Value);
  2968. end;
  2969.  
  2970. Procedure TChartSeries.PrepareForGallery(IsEnabled:Boolean);
  2971. begin
  2972.   FillSampleValues(4);
  2973.   Marks.Visible:=False;
  2974.   FColorEachPoint:=False;
  2975.   if not IsEnabled then SeriesColor:=clSilver;
  2976. end;
  2977.  
  2978. Function TChartSeries.NumSampleValues:Longint;
  2979. Begin
  2980.   result:=26;  { default number or random values at design time }
  2981. end;
  2982.  
  2983. Procedure TChartSeries.CalcRandomBounds( NumValues:Longint;
  2984.                                          Var tmpX,StepX,tmpY,MinY,DifY:Double);
  2985. Var MinX : Double;
  2986.     MaxX : Double;
  2987.     MaxY : Double;
  2988. Begin
  2989.   Randomize;
  2990.   MinY:=0;
  2991.   MaxY:=ChartSamplesMax;
  2992.   if Assigned(FParent) and (FParent.GetMaxValuesCount>0) then
  2993.   begin
  2994.     MinY:=FParent.MinYValue(GetVertAxis);
  2995.     MaxY:=FParent.MaxYValue(GetVertAxis);
  2996.     if MaxY=MinY then
  2997.        if MaxY=0 then MaxY:=ChartSamplesMax
  2998.                  else MaxY:=2.0*MinY;
  2999.     MinX:=FParent.MinXValue(GetHorizAxis);
  3000.     MaxX:=FParent.MaxXValue(GetHorizAxis);
  3001.     if MaxX=MinX then
  3002.        if MaxX=0 then MaxX:=NumValues
  3003.                  else MaxX:=2.0*MinX;
  3004.   end
  3005.   else
  3006.   begin
  3007.     if XValues.DateTime then
  3008.     begin
  3009.       MinX:=Date;
  3010.       MaxX:=MinX+NumValues-1;
  3011.     end
  3012.     else
  3013.     begin
  3014.       MinX:=0;
  3015.       MaxX:=NumValues-1;
  3016.     end;
  3017.   end;
  3018.   StepX:=MaxX-MinX;
  3019.   if NumValues>1 then StepX:=StepX/(NumValues-1);
  3020.   DifY:=MaxY-MinY;
  3021.   if DifY>MaxLongint then DifY:=MaxLongint else
  3022.   if DifY<-MaxLongint then DifY:=-MaxLongint;
  3023.   tmpY:=MinY+Random(Round(DifY));
  3024.   tmpX:=MinX;
  3025. end;
  3026.  
  3027. Procedure TChartSeries.FillSampleValues(NumValues:Longint);
  3028. var t     : Longint;
  3029.     tmp   : Longint;
  3030.     StepX : Double;
  3031.     tmpX  : Double;
  3032.     tmpY  : Double;
  3033.     MinY  : Double;
  3034.     DifY  : Double;
  3035. Begin
  3036.   if NumValues<=0 then Raise Exception.Create(TeeMsg_FillSample);
  3037.   Clear;
  3038.   CalcRandomBounds(NumValues,tmpX,StepX,tmpY,MinY,DifY);
  3039.   tmp:=Round(DifY) div 4;
  3040.   if Assigned(FParent) then FParent.AutoRepaint:=False;
  3041.   for t:=1 to NumValues do
  3042.   Begin
  3043.     tmpY:=Abs(tmpY+Random(tmp)-(tmp div 2));
  3044.     AddXY(tmpX,tmpY{$IFNDEF D4},'', clTeeColor{$ENDIF});
  3045.     tmpX:=tmpX+StepX;
  3046.   end;
  3047.   if Assigned(FParent) then FParent.AutoRepaint:=True;
  3048.   RefreshSeries;
  3049. End;
  3050.  
  3051. Procedure TChartSeries.GalleryChanged3D(Is3D:Boolean);
  3052. begin
  3053.   With ParentChart do
  3054.   begin
  3055.     View3D:=Is3D;
  3056.     ClipPoints:=not Is3D;
  3057.   end;
  3058. end;
  3059.  
  3060. Procedure TChartSeries.SetDoubleProperty(Var Variable:Double; Const Value:Double);
  3061. begin
  3062.   if Variable<>Value then
  3063.   begin
  3064.     Variable:=Value; Repaint;
  3065.   end;
  3066. end;
  3067.  
  3068. Procedure TChartSeries.SetColorProperty(Var Variable:TColor; Value:TColor);
  3069. Begin
  3070.   if Variable<>Value then
  3071.   begin
  3072.     Variable:=Value; Repaint;
  3073.   end;
  3074. end;
  3075.  
  3076. procedure TChartSeries.Assign(Source:TPersistent);
  3077.  
  3078.   Procedure SelfSetDataSources(Value:TList);
  3079.   var t : Integer;
  3080.   begin
  3081.     FDataSources.Clear;
  3082.     for t:=0 to Value.Count-1 do InternalAddDataSource(TComponent(Value[t]));
  3083.   end;
  3084.  
  3085. var t : Integer;
  3086. Begin
  3087.   if Source is TChartSeries then
  3088.   With TChartSeries(Source) do
  3089.   begin
  3090.     Self.Tag         := Tag;
  3091.     Self.DataSource  := nil;
  3092.     if Self.YMandatory and YMandatory then
  3093.     begin
  3094.       Self.FX.Assign(FX);
  3095.       Self.FY.Assign(FY);
  3096.     end
  3097.     else
  3098.     begin
  3099.       Self.FY.Assign(FX);
  3100.       Self.FX.Assign(FY);
  3101.     end;
  3102.     Self.FLabelsSource:=FLabelsSource;
  3103.     Self.FColorSource :=FColorSource;
  3104.  
  3105.     { other lists }
  3106.     for t:=2 to MinLong(Self.ValuesLists.Count-1,ValuesLists.Count-1) do
  3107.         Self.ValuesLists.ValueList[t].Assign(ValuesLists[t]);
  3108.  
  3109.     if (FunctionType<>nil) and (Self.FunctionType=nil) then
  3110.        FunctionType.ParentSeries:=Self;
  3111.  
  3112.     if DataSource=nil then
  3113.     begin
  3114.       if not (csDesigning in ComponentState) then
  3115.       begin
  3116.         Self.FColors.Clear;
  3117.         for t:=0 to FColors.Count-1 do Self.FColors.Add(FColors[t]);
  3118.         Self.FXLabels.Clear;
  3119.         for t:=0 to FXLabels.Count-1 do Self.InsertLabel(t,XLabel[t]);
  3120.         Self.AssignValues(TChartSeries(Source));
  3121.       end;
  3122.     end
  3123.     else SelfSetDataSources(DataSources); { <-- important !!! }
  3124.  
  3125.     Self.FMarks.Assign(FMarks);
  3126.     Self.FColor          := FColor;
  3127.     Self.FColorEachPoint := FColorEachPoint;
  3128.     Self.FTitle          := FTitle;
  3129.     Self.FValueFormat    := FValueFormat;
  3130.     Self.FPercentFormat  := FPercentFormat;
  3131.     Self.FActive         := FActive;
  3132.     Self.FHorizAxis      := FHorizAxis;
  3133.     Self.FVertAxis       := FVertAxis;
  3134.     Self.FRecalcOptions  := FRecalcOptions;
  3135.     Self.FCursor         := FCursor;
  3136.     Self.FShowInLegend   := FShowInLegend;
  3137.     {$IFDEF D3}
  3138.     Self.FStyle          := FStyle;
  3139.     Self.FIdentifier     := FIdentifier;
  3140.     {$ENDIF}
  3141.     Self.CheckDataSource;
  3142.   end
  3143.   else Inherited Assign(Source);
  3144. end;
  3145.  
  3146. Procedure TChartSeries.SetColorEachPoint(Value:Boolean);
  3147. var t : Longint; { <- D1 }
  3148. Begin
  3149.   SetBooleanProperty(FColorEachPoint,Value);
  3150.   if not FColorEachPoint then
  3151.      for t:=0 to Count-1 do ValueColor[t]:=clTeeColor;
  3152. end;
  3153.  
  3154. Procedure TChartSeries.SetShowInLegend(Value:Boolean);
  3155. Begin
  3156.   SetBooleanProperty(FShowInLegend,Value);
  3157. end;
  3158.  
  3159. Procedure TChartSeries.GetBitmapEditor(ABitmap:TBitmap);
  3160. begin
  3161.   TeeGetClassNameBitmap(Self,ABitmap);
  3162. end;
  3163.  
  3164. Procedure TChartSeries.ReplaceList(OldList,NewList:TChartValueList);
  3165. var t:Integer;
  3166. begin
  3167.   With FValuesList do
  3168.   begin
  3169.     t:=IndexOf(NewList);
  3170.     if t<>-1 then Delete(t);
  3171.     for t:=0 to Count-1 do
  3172.     if ValueList[t]=OldList then
  3173.     begin
  3174.       NewList.Name:=OldList.Name;
  3175.       if OldList=FX then FX:=NewList else
  3176.       if OldList=FY then FY:=NewList;
  3177.       TChartValueList(Items[t]).Free;
  3178.       Items[t]:=NewList;
  3179.       Break;
  3180.     end;
  3181.   end;
  3182. end;
  3183.  
  3184. Function TChartSeries.GetxValue(Index:Longint):Double;
  3185. Begin
  3186.   result:=FX.GetValue(Index);
  3187. end;
  3188.  
  3189. Function TChartSeries.GetyValue(Index:Longint):Double;
  3190. Begin
  3191.   result:=FY.GetValue(Index);
  3192. end;
  3193.  
  3194. Procedure TChartSeries.SetYValue(Index:Longint; Const Value:Double);
  3195. Begin
  3196.   FY.SetValue(Index,Value);
  3197.   Repaint;
  3198. end;
  3199.  
  3200. Procedure TChartSeries.SetXValue(Index:Longint; Const Value:Double);
  3201. Begin
  3202.   FX.SetValue(Index,Value);
  3203.   Repaint;
  3204. end;
  3205.  
  3206. Function TChartSeries.GetXLabel(Index:Longint):String;
  3207. Begin
  3208.   if (FXLabels.Count<=Index) or (FXLabels[Index]=nil) then
  3209.      result:=''
  3210.   else
  3211.      result:=StrPas(FXLabels[Index]);
  3212. end;
  3213.  
  3214. Procedure TChartSeries.SetXLabel(Index:Longint; Const AXLabel:String);
  3215. Begin
  3216.   if FXLabels[Index]<>nil then FreeXLabel(Index);
  3217.   FXLabels[Index]:=GetMemLabel(AXLabel);
  3218.   Repaint;
  3219. end;
  3220.  
  3221. Function TChartSeries.GetValueColor(ValueIndex:Longint):TColor;
  3222. Begin
  3223.   if FColors.Count>ValueIndex then
  3224.   Begin
  3225.     result:=TColor(FColors[ValueIndex]);
  3226.     if result=clTeeColor then
  3227.        if FColorEachPoint then result:=GetDefaultColor(ValueIndex)
  3228.                           else result:=FColor;
  3229.   end
  3230.   else result:=FColor;
  3231. end;
  3232.  
  3233. Procedure TChartSeries.SetParentChart(Value:TCustomAxisPanel);
  3234. Begin
  3235.   if FParent<>Value then
  3236.   Begin
  3237.     if Assigned(FParent) then FParent.RemoveSeries(Self);
  3238.     FParent:=Value;
  3239.     RecalcGetAxis;
  3240.     if Assigned(FParent) then FParent.InternalAddSeries(Self);
  3241.   end;
  3242. end;
  3243.  
  3244. Procedure TChartSeries.SetValueColor(ValueIndex:Longint; AColor:TColor);
  3245. Begin
  3246.   FColors[ValueIndex]:=Pointer(AColor);
  3247.   Repaint;
  3248. end;
  3249.  
  3250. Function TChartSeries.GetMemLabel(Const ALabel:String):PChar;
  3251. Begin
  3252.   if ALabel='' then result:=nil
  3253.   else
  3254.   Begin
  3255.     GetMem(result,Length(ALabel)+1);
  3256.     StrPCopy(result,ALabel);
  3257.   end;
  3258. end;
  3259.  
  3260. Procedure TChartSeries.FreeXLabel(ValueIndex:Longint);
  3261. Var tmpText : PChar;
  3262. Begin
  3263.   tmpText:=FXLabels[ValueIndex];
  3264.   if Assigned(tmpText) then FreeMem(tmpText,StrLen(tmpText)+1);
  3265. end;
  3266.  
  3267. Procedure TChartSeries.ClearLists;
  3268. Var t : Longint;
  3269. Begin
  3270.   With FValuesList do for t:=0 to Count-1 do ValueList[t].ClearValues;
  3271.   FColors.Clear;
  3272.   FColors.Capacity:=TeeDefaultCapacity;   
  3273.   for t:=0 to FXLabels.Count-1 do FreeXLabel(t);
  3274.   FXLabels.Clear;
  3275.   FXLabels.Capacity:=TeeDefaultCapacity;   
  3276.   FMarks.ClearPositions;
  3277. end;
  3278.  
  3279. Procedure TChartSeries.Clear;
  3280. begin
  3281.   ClearLists;
  3282.   if Assigned(FOnClearValues) then FOnClearValues(Self);
  3283.   NotifyValue(veClear,0);
  3284.   if Assigned(FParent) and (not (csDestroying in FParent.ComponentState)) then Repaint;
  3285. end;
  3286.  
  3287. Function TChartSeries.AssociatedToAxis(Axis:TCustomChartAxis):Boolean;
  3288. Begin
  3289.   result:=UseAxis and (
  3290.          (Axis.Horizontal and ((FHorizAxis=aBothHorizAxis) or (GetHorizAxis=Axis))) or
  3291.          ((not Axis.Horizontal) and ((FVertAxis=aBothVertAxis) or (GetVertAxis=Axis)))
  3292.         );
  3293. end;
  3294.  
  3295. Procedure TChartSeries.DrawLegendShape(ValueIndex:Longint; Const Rect:TRect);
  3296. begin
  3297.   With FParent,Canvas do
  3298.   begin
  3299.     DoRectangle(Rect);  { <-- rectangle }
  3300.     if Brush.Color=LegendColor then  { <-- color conflict ! }
  3301.     Begin
  3302.       if Brush.Color=clBlack then Pen.Color:=clWhite;
  3303.       Brush.Style:=bsClear;
  3304.       DoRectangle(Rect);  { <-- frame rectangle }
  3305.       Pen.Color:=clBlack;
  3306.     end;
  3307.   end;
  3308. end;
  3309.  
  3310. Function TChartSeries.LegendItemColor(LegendIndex:Longint):TColor;
  3311. begin
  3312.   result:=ValueColor[LegendIndex];
  3313. end;
  3314.  
  3315. Procedure TChartSeries.DrawLegend(ValueIndex:Longint; Const Rect:TRect);
  3316. Var tmpBack  : TColor;
  3317.     tmpStyle : TBrushStyle;
  3318. Begin
  3319.   if (ValueIndex<>-1) or (not ColorEachPoint) then
  3320.   begin
  3321.     with FParent.Canvas.Brush do
  3322.     if ValueIndex=-1 then Color:=SeriesColor
  3323.                      else Color:=LegendItemColor(ValueIndex);
  3324.     if FParent.Canvas.Brush.Color<>clNone then
  3325.     begin
  3326.       tmpBack:=FParent.LegendColor;
  3327.       tmpStyle:=bsSolid;
  3328.       PrepareLegendCanvas(ValueIndex,tmpBack,tmpStyle);
  3329.       if tmpBack=clTeeColor then
  3330.       begin
  3331.         tmpBack:=FParent.LegendColor;
  3332.         if tmpBack=clTeeColor then tmpBack:=FParent.Color;
  3333.       end;
  3334.       With FParent do SetBrushCanvas(Canvas.Brush.Color,tmpStyle,tmpBack);
  3335.       DrawLegendShape(ValueIndex,Rect);
  3336.     end;
  3337.   end;
  3338. End;
  3339.  
  3340. Procedure TChartSeries.PrepareLegendCanvas( ValueIndex:Longint; Var BackColor:TColor;
  3341.                                             Var BrushStyle:TBrushStyle);
  3342. begin { abstract }
  3343. End;
  3344.  
  3345. Procedure TChartSeries.CalcZOrder;
  3346. Begin
  3347.   if FZOrder=TeeAutoZOrder then
  3348.   begin
  3349.     if FParent.View3D then
  3350.     begin
  3351.       Inc(FParent.FMaxZOrder);
  3352.       IZOrder:=FParent.FMaxZOrder;
  3353.     end
  3354.     else IZOrder:=0;
  3355.   end
  3356.   else FParent.FMaxZOrder:=MaxLong(FParent.FMaxZOrder,ZOrder);
  3357. End;
  3358.  
  3359. Function TChartSeries.CalcXPosValue(Const Value:Double):Longint;
  3360. Begin
  3361.   result:=GetHorizAxis.CalcXPosValue(Value);
  3362. end;
  3363.  
  3364. Function TChartSeries.XScreenToValue(ScreenPos:Longint):Double;
  3365. Begin
  3366.   result:=GetHorizAxis.CalcPosPoint(ScreenPos);
  3367. end;
  3368.  
  3369. Function TChartSeries.CalcXSizeValue(Const Value:Double):Longint;
  3370. Begin
  3371.   result:=GetHorizAxis.CalcSizeValue(Value);
  3372. end;
  3373.  
  3374. Function TChartSeries.CalcYPosValue(Const Value:Double):Longint;
  3375. Begin
  3376.   result:=GetVertAxis.CalcYPosValue(Value);
  3377. end;
  3378.  
  3379. Function TChartSeries.CalcPosValue(Const Value:Double):Longint;
  3380. Begin
  3381.   if YMandatory then result:=CalcYPosValue(Value)
  3382.                 else result:=CalcXPosValue(Value);
  3383. end;
  3384.  
  3385. Function TChartSeries.XValueToText(Const AValue:Double):String;
  3386. Begin
  3387.   result:=GetHorizAxis.LabelValue(AValue);
  3388. end;
  3389.  
  3390. Function TChartSeries.YValueToText(Const AValue:Double):String;
  3391. begin
  3392.   result:=GetVertAxis.LabelValue(AValue);
  3393. end;
  3394.  
  3395. Function TChartSeries.YScreenToValue(ScreenPos:Longint):Double;
  3396. Begin
  3397.   result:=GetVertAxis.CalcPosPoint(ScreenPos);
  3398. end;
  3399.  
  3400. Function TChartSeries.CalcYSizeValue(Const Value:Double):Longint;
  3401. Begin
  3402.   result:=GetVertAxis.CalcSizeValue(Value);
  3403. end;
  3404.  
  3405. Function TChartSeries.CalcXPos(ValueIndex:Longint):Integer;
  3406. Begin
  3407.   result:=GetHorizAxis.CalcXPosValue(GetXValue(ValueIndex));
  3408. end;
  3409.  
  3410. Procedure TChartSeries.DoSeriesMouseMove(Shift: TShiftState; X, Y: Integer);
  3411. begin { abstract }
  3412. end;
  3413.  
  3414. Procedure TChartSeries.DoSeriesMouseUp(Button:TMouseButton;
  3415.                                        Shift: TShiftState; X, Y: Integer);
  3416. begin { abstract }
  3417. end;
  3418.  
  3419. Function TChartSeries.DoSeriesClick( Sender:TChartSeries;
  3420.                                      ValueIndex:Longint;
  3421.                                      Button:TMouseButton;
  3422.                                      Shift: TShiftState; X, Y: Integer):Boolean;
  3423. Begin
  3424.   ParentChart.CancelMouse:=False;
  3425.   if (ssDouble in Shift) and Assigned(FOnDblClick) then
  3426.   begin
  3427.     ParentChart.CancelMouse:=True;
  3428.     FOnDblClick(Sender,ValueIndex,Button,Shift,x,y);
  3429.   end
  3430.   else
  3431.   if Assigned(FOnClick) then
  3432.   begin
  3433.     ParentChart.CancelMouse:=True;
  3434.     FOnClick(Sender,ValueIndex,Button,Shift,x,y);
  3435.   end;
  3436.   result:=ParentChart.CancelMouse;
  3437. end;
  3438.  
  3439. Function TChartSeries.CalcYPos(ValueIndex:Longint):Integer;
  3440. begin
  3441.   result:=GetVertAxis.CalcYPosValue(GetyValue(ValueIndex)); { "y" in lowercase , BCB3 bug! }
  3442. end;
  3443.  
  3444. Procedure TChartSeries.Delete(ValueIndex:Longint);
  3445. Var t : Integer;
  3446. Begin
  3447.   With FValuesList do for t:=0 to Count-1 do ValueList[t].Delete(ValueIndex);
  3448.   if FColors.Count>ValueIndex then FColors.Delete(ValueIndex);
  3449.   if FXLabels.Count>ValueIndex then
  3450.   Begin
  3451.     FreeXLabel(ValueIndex);
  3452.     FXLabels.Delete(ValueIndex);
  3453.   end;
  3454.   With FMarks.FPositions do if Count>ValueIndex then Delete(ValueIndex);
  3455.   NotifyValue(veDelete,ValueIndex);
  3456.   Repaint;
  3457. end;
  3458.  
  3459. procedure TChartSeries.SwapValueIndex(a,b:Longint);
  3460. var t : Integer;
  3461. begin
  3462.   With FValuesList do for t:=0 to Count-1 do ValueList[t].FList.Exchange(a,b);
  3463.   FColors.Exchange(a,b);
  3464.   FXLabels.Exchange(a,b);
  3465. end;
  3466.  
  3467. procedure TChartSeries.SetMarks(Value:TSeriesMarks);
  3468. begin
  3469.   FMarks.Assign(Value);
  3470. end;
  3471.  
  3472. Procedure TChartSeries.ClearTempValue(ValueList:TChartValueList);
  3473. Begin
  3474.   ValueList.TempValue:=0;
  3475. End;
  3476.  
  3477. Procedure TChartSeries.SetSeriesColor(AColor:TColor);
  3478. Begin
  3479.   SetColorProperty(FColor,AColor);
  3480. end;
  3481.  
  3482. Function TChartSeries.MaxXValue:Double;
  3483. Begin
  3484.   result:=FX.MaxValue;
  3485. end;
  3486.  
  3487. Function TChartSeries.MaxYValue:Double;
  3488. Begin
  3489.   result:=FY.MaxValue;
  3490. end;
  3491.  
  3492. Function TChartSeries.MinXValue:Double;
  3493. Begin
  3494.   result:=FX.MinValue;
  3495. end;
  3496.  
  3497. Function TChartSeries.MinYValue:Double;
  3498. Begin
  3499.   result:=FY.MinValue;
  3500. end;
  3501.  
  3502. Function TChartSeries.MaxZValue:Double;
  3503. begin
  3504.   result:=ZOrder;
  3505. end;
  3506.  
  3507. Function TChartSeries.MinZValue:Double;
  3508. begin
  3509.   result:=ZOrder;
  3510. end;
  3511.  
  3512. Function TChartSeries.MaxMarkWidth:Longint;
  3513. var t : Longint;
  3514. Begin
  3515.   result:=0;
  3516.   for t:=0 to Count-1 do
  3517.       result:=MaxLong(result,ParentChart.Canvas.TextWidth(GetMarkText(t)));
  3518. end;
  3519.  
  3520. Procedure TChartSeries.AddLinkedSeries(ASeries:TChartSeries);
  3521. Begin
  3522.   if FLinkedSeries.IndexOf(ASeries)=-1 then FLinkedSeries.Add(ASeries);
  3523. end;
  3524.  
  3525. Procedure TChartSeries.RemoveDataSource(Value:TComponent);
  3526. begin
  3527.   FDataSources.Remove(Value);
  3528.   CheckDataSource;
  3529. end;
  3530.  
  3531. Procedure TChartSeries.RemoveLinkedSeries(ASeries:TChartSeries);
  3532. Begin
  3533.   if Assigned(FLinkedSeries) then FLinkedSeries.Remove(ASeries);
  3534. end;
  3535.  
  3536. Procedure TChartSeries.NotifyValue(ValueEvent:TValueEvent; ValueIndex:Longint);
  3537. var t : Integer;
  3538. Begin
  3539.   for t:=0 to FLinkedSeries.Count-1 do
  3540.   if FLinkedSeries[t]<>nil then
  3541.   With TChartSeries(FLinkedSeries[t]) do
  3542.     if DataSources.IndexOf(Self)<>-1 then { is this necessary? }
  3543.     Case ValueEvent of
  3544.       veClear  : if rOnClear in FRecalcOptions then Clear;
  3545.       veDelete : if rOnDelete in FRecalcOptions then
  3546.                     if FunctionType=nil then DeletedValue(Self,ValueIndex);
  3547.       veAdd    : if rOnInsert in FRecalcOptions then
  3548.                     if FunctionType=nil then AddedValue(Self,ValueIndex);
  3549.       veModify : if rOnModify in FRecalcOptions then AddValues(Self);
  3550.       veRefresh: AddValues(Self);
  3551.     end;
  3552. end;
  3553.  
  3554. Function TChartSeries.UseAxis:Boolean;
  3555. begin
  3556.   result:=True;
  3557. end;
  3558.  
  3559. Procedure TChartSeries.Loaded;
  3560. var t : Integer;
  3561. begin
  3562.   inherited Loaded;
  3563.   if Assigned(FTempDataSources) then
  3564.   begin
  3565.     if FTempDataSources.Count>0 then
  3566.     begin
  3567.       FDataSources.Clear;
  3568.       for t:=0 to FTempDataSources.Count-1 do
  3569.           InternalAddDataSource( Owner.FindComponent(FTempDataSources[t]) );
  3570.     end;
  3571.     FTempDataSources.Free;
  3572.   end;
  3573.   CheckDatasource;
  3574. end;
  3575.  
  3576. Destructor TChartSeries.Destroy;
  3577. Var t : Integer;
  3578. Begin
  3579.   FTeeFunction.Free;
  3580.   FTeeFunction:=nil;
  3581.  
  3582.   RemoveAllLinkedSeries;
  3583.  
  3584.   FDataSources.Free;
  3585.   FDataSources:=nil;
  3586.  
  3587.   for t:=0 to FLinkedSeries.Count-1 do
  3588.       TChartSeries(FLinkedSeries[t]).RemoveDataSource(Self);
  3589.  
  3590.   Clear;
  3591.  
  3592.   FLinkedSeries.Free;
  3593.   FLinkedSeries:=nil;
  3594.  
  3595.   With FValuesList do for t:=0 to Count-1 do ValueList[t].Free;
  3596.   FValuesList.Free;
  3597.  
  3598.   FColors.Free;
  3599.   FXLabels.Free;
  3600.   FMarks.Free;
  3601.   if Assigned(FParent) then ParentChart:=nil;
  3602.   inherited Destroy;
  3603. end;
  3604.  
  3605. Procedure TChartSeries.SetCustomHorizAxis(Value:TChartAxis);
  3606. begin
  3607.   if Value<>FCustomHorizAxis then
  3608.   begin
  3609.     FCustomHorizAxis:=Value;
  3610.     if Assigned(Value) then FHorizAxis:=aCustomHorizAxis
  3611.                        else FHorizAxis:=aBottomAxis;
  3612.     RecalcGetAxis;
  3613.     Repaint;
  3614.   end;
  3615. end;
  3616.  
  3617. Function TChartSeries.GetZOrder:Integer;
  3618. begin
  3619.   if FZOrder=TeeAutoZOrder then result:=IZOrder
  3620.                            else result:=FZOrder;
  3621. end;
  3622.  
  3623. Procedure TChartSeries.SetZOrder(Value:Integer);
  3624. begin
  3625.   SetIntegerProperty(FZOrder,Value);
  3626.   if FZOrder=TeeAutoZOrder then IZOrder:=0 else IZOrder:=FZOrder;
  3627. end;
  3628.  
  3629. Procedure TChartSeries.SetCustomVertAxis(Value:TChartAxis);
  3630. begin
  3631.   if Value<>FCustomVertAxis then
  3632.   begin
  3633.     FCustomVertAxis:=Value;
  3634.     if Assigned(Value) then FVertAxis:=aCustomVertAxis
  3635.                        else FVertAxis:=aLeftAxis;
  3636.     RecalcGetAxis;
  3637.     Repaint;
  3638.   end;
  3639. end;
  3640.  
  3641. { TChartSeriesList }
  3642. procedure TChartSeriesList.SetSeries(Index:Integer; Series:TChartSeries);
  3643. begin
  3644.   inherited Items[Index]:=Series;
  3645. end;
  3646.  
  3647. function TChartSeriesList.GetSeries(Index:Integer):TChartSeries;
  3648. begin
  3649.   result:=TChartSeries(inherited Items[Index]);
  3650. end;
  3651.  
  3652. Function TChartSeriesList.CountActive:Longint;
  3653. var t : Integer;
  3654. Begin
  3655.   result:=0;
  3656.   for t:=0 to Count-1 do if TChartSeries(Items[t]).FActive then Inc(result);
  3657. end;
  3658.  
  3659. { TChartAxisTitle }
  3660. Procedure TChartAxisTitle.Assign(Source:TPersistent);
  3661. Begin
  3662.   if Source is TChartAxisTitle then
  3663.   With TChartAxisTitle(Source) do
  3664.   Begin
  3665.     Self.FAxis    := FAxis;
  3666.     Self.FAngle   := FAngle;
  3667.     Self.FCaption := FCaption;
  3668.   end;
  3669.   inherited Assign(Source);
  3670. end;
  3671.  
  3672. Function TChartAxisTitle.IsAngleStored:Boolean;
  3673. begin
  3674.   result:=FAngle<>FAxis.IDefaultTitleAngle;
  3675. end;
  3676.  
  3677. Procedure TChartAxisTitle.SetAngle(Value:Integer);
  3678. Begin
  3679.   if FAngle<>Value then
  3680.   begin
  3681.     TeeCheckAngle(Value,TeeMsg_AxisTitle);
  3682.     FAngle:=Value;
  3683.     Repaint;
  3684.   end;
  3685. end;
  3686.  
  3687. Procedure TChartAxisTitle.SetCaption(Const Value:String);
  3688. Begin
  3689.   ParentChart.SetStringProperty(FCaption,Value);
  3690. end;
  3691.  
  3692. { TCustomChartAxis }
  3693. Constructor TCustomChartAxis.Create(AOwner: TCustomAxisPanel);
  3694. Begin
  3695.   inherited Create;
  3696.   FParentChart:=AOwner;
  3697.   FLabels:=True;
  3698.   FLogarithmicBase:=10;
  3699.   FAutomatic:=True;
  3700.   FAutomaticMaximum:=True;
  3701.   FAutomaticMinimum:=True;
  3702.   FLabelsSeparation:=10; { % }
  3703.   FAxisValuesFormat:=TeeMsg_DefValueFormat;
  3704.   FLabelStyle:=talAuto;
  3705.   FLabelsOnAxis:=True;
  3706.   FLabelsFont:=CreateDefaultFont(FParentChart.CanvasChanged);
  3707.  
  3708.   FTickOnLabelsOnly:=True;
  3709.  
  3710.   IDefaultTitleAngle:=0;
  3711.   FAxisTitle:=TChartAxisTitle.Create(ParentChart);
  3712.   FAxisTitle.FAxis:=Self;
  3713.  
  3714.   FTicks:=TDarkGrayPen.Create(ParentChart.CanvasChanged);
  3715.   FTickLength:=4;
  3716.  
  3717.   FMinorTicks:=TDarkGrayPen.Create(ParentChart.CanvasChanged);
  3718.   FMinorTickLength:=2;
  3719.   FMinorTickCount:=3;
  3720.  
  3721.   FTicksInner:=TDarkGrayPen.Create(ParentChart.CanvasChanged);
  3722.   FGrid:=TDottedGrayPen.Create(ParentChart.CanvasChanged);
  3723.   FAxis:=TChartAxisPen.Create(ParentChart.CanvasChanged);
  3724.  
  3725.   FVisible:=True;
  3726.   RoundFirstLabel:=True;
  3727.   FExactDateTime:=True;
  3728.   FParentChart.FAxes.Add(Self);
  3729.   FStartPosition:=0;
  3730.   FEndPosition:=100;
  3731.   FPositionPercent:=0;
  3732. end;
  3733.  
  3734.  
  3735. Procedure TCustomChartAxis.IncDecDateTime( Increment:Boolean;
  3736.                                            Var Value:Double;
  3737.                                            Const AnIncrement:Double;
  3738.                                            tmpWhichDateTime:TDateTimeStep);
  3739. begin
  3740.  TeeDateTimeIncrement( FExactDateTime and IAxisDateTime and
  3741.                        (tmpWhichDateTime>=dtHalfMonth),
  3742.                        Increment,
  3743.                        Value,
  3744.                        AnIncrement,
  3745.                        tmpWhichDateTime );
  3746. end;
  3747.  
  3748. { An axis is "DateTime" if at least one Active Series with
  3749.   datetime values is associated to it }
  3750. Function TCustomChartAxis.IsDateTime:Boolean;
  3751. Var tmpSeries : Longint;
  3752. Begin
  3753.   With ParentChart do
  3754.   for tmpseries:=0 to FSeriesList.Count-1 do
  3755.   With Series[tmpSeries] do
  3756.   if FActive then
  3757.       if AssociatedToAxis(Self) then
  3758.       begin
  3759.         if Self.Horizontal then result:=FX.DateTime
  3760.                            else result:=FY.DateTime;
  3761.         exit;
  3762.       end;
  3763.   result:=False;
  3764. end;
  3765.  
  3766. Procedure TCustomChartAxis.SetTicks(Value:TDarkGrayPen);
  3767. Begin
  3768.   FTicks.Assign(Value);
  3769. end;
  3770.  
  3771. Procedure TCustomChartAxis.SetMinorTicks(Value:TDarkGrayPen);
  3772. Begin
  3773.   FMinorTicks.Assign(Value);
  3774. end;
  3775.  
  3776. Procedure TCustomChartAxis.SetTicksInner(Value:TDarkGrayPen);
  3777. Begin
  3778.   FTicksInner.Assign(Value);
  3779. end;
  3780.  
  3781. Procedure TCustomChartAxis.SetGrid(Value:TDottedGrayPen);
  3782. Begin
  3783.   FGrid.Assign(Value);
  3784. end;
  3785.  
  3786. Procedure TCustomChartAxis.SetGridCentered(Value:Boolean);
  3787. Begin
  3788.   ParentChart.SetBooleanProperty(FGridCentered,Value);
  3789. end;
  3790.  
  3791. Procedure TCustomChartAxis.SetAxis(Value:TChartAxisPen);
  3792. Begin
  3793.   FAxis.Assign(Value);
  3794. end;
  3795.  
  3796. Destructor TCustomChartAxis.Destroy;
  3797. begin
  3798.   FMinorTicks.Free;
  3799.   FTicks.Free;
  3800.   FTicksInner.Free;
  3801.   FGrid.Free;
  3802.   FAxis.Free;
  3803.   FAxisTitle.Free;
  3804.   FLabelsFont.Free;
  3805.   inherited Destroy;
  3806. end;
  3807.  
  3808. {$IFNDEF D1}
  3809. Function TCustomChartAxis.IsPosStored:Boolean;
  3810. begin
  3811.   result:=FEndPosition<>0;
  3812. end;
  3813.  
  3814. Function TCustomChartAxis.IsStartStored:Boolean;
  3815. begin
  3816.   result:=FEndPosition<>0;
  3817. end;
  3818.  
  3819. Function TCustomChartAxis.IsEndStored:Boolean;
  3820. begin
  3821.   result:=FEndPosition<>100;
  3822. end;
  3823. {$ENDIF}
  3824.  
  3825. Function TCustomChartAxis.CalcPosPoint(Value:Longint):Double;
  3826.  
  3827.   Function InternalCalcPos(Const A,B:Double):Double;
  3828.   begin
  3829.     if (Horizontal and FInverted) or
  3830.        ((not Horizontal) and (not FInverted)) then result:=A
  3831.                                               else result:=B
  3832.   end;
  3833.  
  3834. var tmp    : Double;
  3835.     LogMin : Double;
  3836.     LogMax : Double;
  3837. Begin
  3838.   if FLogarithmic then
  3839.   Begin
  3840.     if Value=IStartPos then result:=InternalCalcPos(IMaximum,IMinimum)
  3841.     else
  3842.     if Value=IEndPos then result:=InternalCalcPos(IMinimum,IMaximum)
  3843.     else
  3844.     begin
  3845.       tmp:=InternalCalcLog(LogMax,LogMin);
  3846.       if tmp=0 then result:=IMinimum
  3847.       else
  3848.       begin
  3849.         if FInverted then tmp:=((IEndPos-Value)*tmp/IAxisSize)
  3850.                      else tmp:=((Value-IStartPos)*tmp/IAxisSize);
  3851.         if Horizontal then result:=Exp(LogMin+tmp)
  3852.                       else result:=Exp(LogMax-tmp);
  3853.       end;
  3854.     end;
  3855.   end
  3856.   else
  3857.   if IAxisSize>0 then
  3858.   begin
  3859.     if FInverted then tmp:=IEndPos-Value
  3860.                  else tmp:=Value-IStartPos;
  3861.     tmp:=tmp*IRange/IAxisSize;
  3862.     if Horizontal then result:=IMinimum+tmp
  3863.                   else result:=IMaximum-tmp;
  3864.   end
  3865.   else result:=0;
  3866. end;
  3867.  
  3868. Procedure TCustomChartAxis.SetDateTimeFormat(Const Value:String);
  3869. Begin
  3870.   ParentChart.SetStringProperty(FDateTimeFormat,Value);
  3871. end;
  3872.  
  3873. procedure TCustomChartAxis.SetAxisTitle(Value:TChartAxisTitle);
  3874. begin
  3875.   FAxisTitle.Assign(Value);
  3876. end;
  3877.  
  3878. procedure TCustomChartAxis.SetStartPosition(Const Value:Double);
  3879. begin
  3880.   ParentChart.SetDoubleProperty(FStartPosition,Value);
  3881. end;
  3882.  
  3883. procedure TCustomChartAxis.SetEndPosition(Const Value:Double);
  3884. begin
  3885.   ParentChart.SetDoubleProperty(FEndPosition,Value);
  3886. end;
  3887.  
  3888. procedure TCustomChartAxis.SetPositionPercent(Const Value:Double);
  3889. begin
  3890.   ParentChart.SetDoubleProperty(FPositionPercent,Value);
  3891. end;
  3892.  
  3893. procedure TCustomChartAxis.SetRoundFirstLabel(Value:Boolean);
  3894. begin
  3895.   ParentChart.SetBooleanProperty(FRoundFirstLabel,Value);
  3896. end;
  3897.  
  3898. Procedure TCustomChartAxis.SetLabelsMultiLine(Value:Boolean);
  3899. begin
  3900.   ParentChart.SetBooleanProperty(FLabelsMultiLine,Value);
  3901. end;
  3902.  
  3903. procedure TCustomChartAxis.SetTickOnLabelsOnly(Value:Boolean);
  3904. begin
  3905.   ParentChart.SetBooleanProperty(FTickOnLabelsOnly,Value);
  3906. end;
  3907.  
  3908. Function TCustomChartAxis.CalcDateTimeIncrement(MaxNumLabels:Longint):Double;
  3909. Var TempNumLabels : Longint;
  3910. Begin
  3911.   result:=MaxDouble(FDesiredIncrement,DateTimeStep[dtOneSecond]);
  3912.   if (result>0) and (MaxNumLabels>0) then
  3913.   begin
  3914.     if (IRange/Result)>1000000 then Result:=IRange/1000000;
  3915.     Repeat
  3916.       TempNumLabels:=Round(IRange/result);
  3917.       if TempNumLabels>MaxNumLabels then
  3918.          if result<DateTimeStep[dtOneYear] then
  3919.             result:=NextDateTimeStep(result)
  3920.          else
  3921.             result:=2.0*result;
  3922.     Until (TempNumLabels<=MaxNumLabels){ or (result=DateTimeStep[dtOneYear])};
  3923.   end;
  3924.   result:=MaxDouble(result,DateTimeStep[dtOneSecond]);
  3925. end;
  3926.  
  3927. Function TCustomChartAxis.InternalCalcLabelsIncrement(MaxNumLabels:Longint):Double;
  3928. Var TempNumLabels : Longint;
  3929.     tmp           : Double;
  3930. Begin
  3931.   if FDesiredIncrement<=0 then
  3932.   Begin
  3933.     Result:=Abs(IRange);
  3934.     if Result<1 then Result:=MinAxisIncrement
  3935.                 else Result:=1;
  3936.   end
  3937.   else
  3938.     Result:=FDesiredIncrement;
  3939.   if MaxNumLabels>0 then
  3940.   Begin
  3941.     TempNumLabels:=MaxNumLabels+1;
  3942.     if LabelsSeparation>0 then
  3943.     Repeat
  3944.       tmp:=IRange/Result;
  3945.       if Abs(tmp)<MaxLongint then
  3946.       begin
  3947.         TempNumLabels:=Round(tmp);
  3948.         if TempNumLabels>MaxNumLabels then Result:=TeeNextStep(Result);
  3949.       end
  3950.       else Result:=TeeNextStep(Result);
  3951.     Until (TempNumLabels<=MaxNumLabels){ or (result>1000000000)};
  3952.   end;
  3953.   result:=MaxDouble(Result,MinAxisIncrement);
  3954. end;
  3955.  
  3956. Function TCustomChartAxis.CalcLabelsIncrement(MaxNumLabels:Longint):Double;
  3957. Begin
  3958.   if MaxNumLabels>0 then
  3959.   Begin
  3960.     if IAxisDateTime then result:=CalcDateTimeIncrement(MaxNumLabels)
  3961.                      else result:=InternalCalcLabelsIncrement(MaxNumLabels);
  3962.   end
  3963.   else
  3964.   if IAxisDateTime then result:=DateTimeStep[dtOneSecond]
  3965.                    else result:=MinAxisIncrement;
  3966. end;
  3967.  
  3968. Function TCustomChartAxis.LabelWidth(Const Value:Double):Longint;
  3969. var tmp:Integer;
  3970. Begin
  3971.   result:=ParentChart.MultiLineTextWidth(LabelValue(Value),tmp);
  3972.   if (FLabelsAngle=90) or (FLabelsAngle=270) then
  3973.      result:=ParentChart.Canvas.FontHeight*tmp;
  3974. End;
  3975.  
  3976. Function TCustomChartAxis.LabelHeight(Const Value:Double):Longint;
  3977. var tmp:Integer;
  3978. Begin
  3979.   result:=ParentChart.MultiLineTextWidth(LabelValue(Value),tmp);
  3980.   if (FLabelsAngle=0) or (FLabelsAngle=180) then
  3981.      result:=ParentChart.Canvas.FontHeight*tmp;
  3982. End;
  3983.  
  3984. Function TCustomChartAxis.IsMaxStored:Boolean;
  3985. Begin { dont store max property if automatic }
  3986.   result:=(not FAutomatic) and (not FAutomaticMaximum);
  3987. end;
  3988.  
  3989. Function TCustomChartAxis.IsMinStored:Boolean;
  3990. Begin{ dont store min property if automatic }
  3991.   result:=(not FAutomatic) and (not FAutomaticMinimum);
  3992. end;
  3993.  
  3994. Function TCustomChartAxis.CalcXYIncrement(MaxLabelSize:Integer):Double;
  3995. begin
  3996.   if FLabelsSeparation>0 then
  3997.      Inc(MaxLabelSize,Round(0.01*FLabelsSeparation*MaxLabelSize));
  3998.   if MaxLabelSize>0 then
  3999.      result:=CalcLabelsIncrement(Round((1.0*IAxisSize)/MaxLabelSize))
  4000.   else
  4001.      result:=CalcLabelsIncrement(1);
  4002. end;
  4003.  
  4004. Function TCustomChartAxis.CalcIncrement:Double;
  4005. Begin
  4006.   if Horizontal then
  4007.      result:=CalcXYIncrement( MaxLong(LabelWidth(IMinimum),LabelWidth(IMaximum)) )
  4008.   else
  4009.      result:=CalcXYIncrement( MaxLong(LabelHeight(IMinimum),LabelHeight(IMaximum)) );
  4010. End;
  4011.  
  4012. Procedure TCustomChartAxis.AdjustMaxMinRect(Const Rect:TRect);
  4013. Var tmpMin : Double;
  4014.     tmpMax : Double;
  4015.  
  4016.     Procedure RecalcAdjustedMinMax(Pos1,Pos2:Integer);
  4017.     Var OldStart : Integer;
  4018.         OldEnd   : Integer;
  4019.     Begin
  4020.       OldStart :=IStartPos;
  4021.       OldEnd   :=IEndPos;
  4022.       Inc(IStartPos,Pos1);
  4023.       Dec(IEndPos,Pos2);
  4024.       IAxisSize:=IEndPos-IStartPos;
  4025.       tmpMin:=CalcPosPoint(OldStart);
  4026.       tmpMax:=CalcPosPoint(OldEnd);
  4027.     end;
  4028.  
  4029. Begin
  4030.   With ParentChart do
  4031.   begin
  4032.     with Rect do
  4033.     if Horizontal then ReCalcAdjustedMinMax(Left,Right)
  4034.                   else ReCalcAdjustedMinMax(Top,Bottom);
  4035.     InternalCalcPositions;
  4036.     IMinimum:=tmpMin;
  4037.     IMaximum:=tmpMax;
  4038.   end;
  4039.   if IMinimum>IMaximum then SwapDouble(IMinimum,IMaximum);
  4040.   IRange:=IMaximum-IMinimum;
  4041. end;
  4042.  
  4043. Procedure TCustomChartAxis.CalcMinMax(Var AMin,AMax:Double);
  4044. Begin
  4045.   if FAutomatic or FAutomaticMaximum then
  4046.      AMax:=ParentChart.InternalMinMax(Self,False,Horizontal);
  4047.   if FAutomatic or FAutomaticMinimum then
  4048.      AMin:=ParentChart.InternalMinMax(Self,True,Horizontal);
  4049. end;
  4050.  
  4051. Procedure TCustomChartAxis.AdjustMaxMin;
  4052. Begin
  4053.   CalcMinMax(FMinimumValue,FMaximumValue);
  4054.   IMaximum:=FMaximumValue;
  4055.   IMinimum:=FMinimumValue;
  4056.   IRange  :=IMaximum-IMinimum;
  4057. end;
  4058.  
  4059. procedure TCustomChartAxis.Assign(Source: TPersistent);
  4060. Begin
  4061.   if Source is TCustomChartAxis then
  4062.   With TCustomChartAxis(Source) do
  4063.   Begin
  4064.     Self.FVisible             :=FVisible;
  4065.     Self.FLabels              :=FLabels;
  4066.     Self.FLabelsAngle         :=FLabelsAngle;
  4067.     Self.FLabelsFont.Assign(FLabelsFont);
  4068.     Self.FLabelsSeparation    :=FLabelsSeparation;
  4069.     Self.FLabelsSize          :=FLabelsSize;
  4070.     Self.FTitleSize           :=FTitleSize;
  4071.     Self.FLabelStyle          :=FLabelStyle;
  4072.     Self.FLabelsOnAxis        :=FLabelsOnAxis;
  4073.     Self.FTicks.Assign(FTicks);
  4074.     Self.FMinorTicks.Assign(FMinorTicks);
  4075.     Self.FTicksInner.Assign(FTicksInner);
  4076.     Self.FGrid.Assign(FGrid);
  4077.     Self.FAxis.Assign(FAxis);
  4078.     Self.FTickLength          :=FTickLength;
  4079.     Self.FMinorTickLength     :=FMinorTickLength;
  4080.     Self.FMinorTickCount      :=FMinorTickCount;
  4081.     Self.FTickInnerLength     :=FTickInnerLength;
  4082.     Self.FAxisValuesFormat    :=FAxisValuesFormat;
  4083.     Self.FDesiredIncrement    :=FDesiredIncrement;
  4084.     Self.FMaximumValue        :=FMaximumValue;
  4085.     Self.FMinimumValue        :=FMinimumValue;
  4086.     Self.FAutomatic           :=FAutomatic;
  4087.     Self.FAutomaticMaximum    :=FAutomaticMaximum;
  4088.     Self.FAutomaticMinimum    :=FAutomaticMinimum;
  4089.     Self.FAxisTitle.Assign(FAxisTitle);
  4090.     Self.FDateTimeFormat      :=FDateTimeFormat;
  4091.     Self.FLogarithmic         :=FLogarithmic;
  4092.     Self.FLogarithmicBase     :=FLogarithmicBase;
  4093.     Self.FInverted            :=FInverted;
  4094.     Self.FExactDateTime       :=FExactDateTime;
  4095.     Self.FRoundFirstLabel     :=FRoundFirstLabel;
  4096.     Self.FTickOnLabelsOnly    :=FTickOnLabelsOnly;
  4097.     Self.IsDepthAxis          :=IsDepthAxis;
  4098.     Self.FStartPosition       :=FStartPosition;
  4099.     Self.FEndPosition         :=FEndPosition;
  4100.     Self.FPositionPercent     :=FPositionPercent;
  4101.   end
  4102.   else inherited Assign(Source);
  4103. end;
  4104.  
  4105. Function TCustomChartAxis.LabelValue(Const Value:Double):String;
  4106. Begin
  4107.   if IAxisDateTime then
  4108.   begin
  4109.     if Value>=0 then
  4110.     Begin
  4111.       if FDateTimeFormat='' then
  4112.          DateTimeToString(result,DateTimeDefaultFormat(IRange),Value)
  4113.       else
  4114.          DateTimeToString(result,FDateTimeFormat,Value)
  4115.     end
  4116.     else result:='';
  4117.   end
  4118.   else result:=FormatFloat(FAxisValuesFormat,Value);
  4119.   if Assigned(ParentChart.FOnGetAxisLabel) then
  4120.      ParentChart.FOnGetAxisLabel(TChartAxis(Self),nil,-1,Result);
  4121.   if FLabelsMultiLine then TeeSplitInLines(Result,' ');
  4122. end;
  4123.  
  4124. Function TCustomChartAxis.CalcLabelStyle:TAxisLabelStyle;
  4125. var {tmpSeries : TChartSeries;}
  4126.     t         : Integer;
  4127. Begin
  4128.  if FLabelStyle=talAuto then
  4129.  Begin
  4130.    if IsDepthAxis then
  4131.    begin
  4132.      result:=talText;
  4133.      With ParentChart do
  4134.      if SeriesList.CountActive>0 then
  4135.      for t:=0 to FSeriesList.Count-1 do
  4136.      With Series[t] do
  4137.      if Active then
  4138.         if HasZValues or (MinZValue<>MaxZValue) then
  4139.         begin
  4140.           result:=talValue;
  4141.           break;
  4142.         end;
  4143.    end
  4144.    else
  4145.    begin
  4146.      result:=talNone;
  4147.      for t:=0 to ParentChart.SeriesList.Count-1 do
  4148.      With ParentChart.Series[t] do
  4149.      if Active and AssociatedToAxis(Self) then
  4150.      begin
  4151.        result:=talValue;
  4152.        if (Horizontal and {tmpSeries.}YMandatory) or
  4153.           ((not Horizontal) and (not {tmpSeries.}YMandatory)) then
  4154.           if (FXLabels.Count>0) and (FXLabels.First<>nil) then
  4155.           begin
  4156.             result:=talText;
  4157.             break;
  4158.           end;
  4159.      end;
  4160.  
  4161.    {  tmpSeries:=ParentChart.GetAxisSeries(Self);
  4162.      if not Assigned(tmpSeries) then result:=talNone
  4163.      else
  4164.      Begin
  4165.        if (Horizontal and tmpSeries.YMandatory) or
  4166.           ((not Horizontal) and (not tmpSeries.YMandatory)) then
  4167.        begin
  4168.          if (tmpSeries<>nil) and (tmpSeries.FXLabels.Count>0) and
  4169.             (tmpSeries.FXLabels.First<>nil) then
  4170.             result:=talText
  4171.          else
  4172.             result:=talValue;
  4173.        end
  4174.        else result:=talValue;
  4175.      end;}
  4176.    end;
  4177.  end
  4178.  else result:=FLabelStyle;
  4179. End;
  4180.  
  4181. Function TCustomChartAxis.MaxLabelsWidth:Longint;
  4182.  
  4183.   Function MaxLabelsValueWidth:Longint;
  4184.   var tmp    : Double;
  4185.       tmpA   : Double;
  4186.       tmpB   : Double;
  4187.       OldGetAxisLabel : TAxisOnGetLabel;
  4188.       tmpNum : Integer;
  4189.   begin
  4190.     if (IsDateTime and FExactDateTime) or RoundFirstLabel then
  4191.     begin
  4192.       tmp:=CalcIncrement;
  4193.       tmpA:=tmp*Int(IMinimum/tmp);
  4194.       tmpB:=tmp*Int(IMaximum/tmp);
  4195.     end
  4196.     else
  4197.     begin
  4198.       tmpA:=IMinimum;
  4199.       tmpB:=IMaximum;
  4200.     end;
  4201.     With ParentChart do
  4202.     begin
  4203.       OldGetAxisLabel:=FOnGetAxisLabel;
  4204.       FOnGetAxisLabel:=nil;
  4205.       With Canvas do
  4206.            result:=TextWidth(' ')+ MaxLong( MultiLineTextWidth(LabelValue(tmpA),tmpNum),
  4207.                                             MultiLineTextWidth(LabelValue(tmpB),tmpNum));
  4208.       FOnGetAxisLabel:=OldGetAxisLabel;
  4209.     end;
  4210.   end;
  4211.  
  4212. Begin
  4213.   Case CalcLabelStyle of
  4214.     talValue : result:=MaxLabelsValueWidth;
  4215.     talMark  : result:=ParentChart.MaxMarkWidth;
  4216.     talText  : result:=ParentChart.MaxTextWidth;
  4217.   else
  4218.   {talNone : } result:=0;
  4219.   end;
  4220. end;
  4221.  
  4222. Procedure TCustomChartAxis.SetLabels(Value:Boolean);
  4223. Begin
  4224.   ParentChart.SetBooleanProperty(FLabels,Value);
  4225. end;
  4226.  
  4227. Procedure TCustomChartAxis.SetLabelsFont(Value:TFont);
  4228. begin
  4229.   FLabelsFont.Assign(Value);
  4230. end;
  4231.  
  4232. Function TCustomChartAxis.IsFontStored:Boolean;
  4233. begin
  4234.   result:=not IsDefaultFont(FLabelsFont);
  4235. end;
  4236.  
  4237. Procedure TCustomChartAxis.SetAutomatic(Value:Boolean);
  4238. Begin
  4239.   ParentChart.SetBooleanProperty(FAutomatic,Value);
  4240.   if {Value and} (not (csLoading in ParentChart.ComponentState)) then { 4.01 }
  4241.   begin
  4242.     FAutomaticMinimum:=Value;
  4243.     FAutomaticMaximum:=Value;
  4244.   end;
  4245. end;
  4246.  
  4247. Procedure TCustomChartAxis.SetAutomaticMinimum(Value:Boolean);
  4248. Begin
  4249.   ParentChart.SetBooleanProperty(FAutomaticMinimum,Value);
  4250.   if Value then
  4251.   begin { if both are automatic, then Automatic should be True too }
  4252.     if FAutomaticMaximum then FAutomatic:=True;
  4253.   end
  4254.   else FAutomatic:=False;
  4255. end;
  4256.  
  4257. Procedure TCustomChartAxis.SetAutomaticMaximum(Value:Boolean);
  4258. Begin
  4259.   ParentChart.SetBooleanProperty(FAutomaticMaximum,Value);
  4260.   if Value then
  4261.   begin { if both are automatic, then Automatic should be True too }
  4262.     if FAutomaticMinimum then FAutomatic:=True;
  4263.   end
  4264.   else FAutomatic:=False;
  4265. end;
  4266.  
  4267. Function TCustomChartAxis.IsAxisValuesFormatStored:Boolean;
  4268. begin
  4269.   result:=FAxisValuesFormat<>TeeMsg_DefValueFormat;
  4270. end;
  4271.  
  4272. Procedure TCustomChartAxis.SetValuesFormat(Const Value:String);
  4273. Begin
  4274.   ParentChart.SetStringProperty(FAxisValuesFormat,Value);
  4275. end;
  4276.  
  4277. Procedure TCustomChartAxis.SetInverted(Value:Boolean);
  4278. Begin
  4279.   ParentChart.SetBooleanProperty(FInverted,Value);
  4280. end;
  4281.  
  4282. Procedure TCustomChartAxis.InternalSetInverted(Value:Boolean);
  4283. Begin
  4284.   FInverted:=Value;
  4285. end;
  4286.  
  4287. Procedure TCustomChartAxis.SetLogarithmicBase(Value:Integer);
  4288. begin
  4289.   if FLogarithmicBase<2 then raise AxisException.Create(TeeMsg_AxisLogBase);
  4290.   ParentChart.SetIntegerProperty(FLogarithmicBase,Value);
  4291. end;
  4292.  
  4293. Procedure TCustomChartAxis.SetLogarithmic(Value:Boolean);
  4294. Begin
  4295.   if Value and IsDateTime then
  4296.      Raise AxisException.Create(TeeMsg_AxisLogDateTime);
  4297.   if Value then
  4298.   begin
  4299.     AdjustMaxMin;
  4300.     if ((IMinimum<0) or (IMaximum<0)) then
  4301.        Raise AxisException.Create(TeeMsg_AxisLogNotPositive);
  4302.   end;
  4303.   ParentChart.SetBooleanProperty(FLogarithmic,Value);
  4304. End;
  4305.  
  4306. Procedure TCustomChartAxis.SetLabelsAngle(Value:Integer);
  4307. Begin
  4308.   TeeCheckAngle(Value,TeeMsg_AxisLabels);
  4309.   ParentChart.SetIntegerProperty(FLabelsAngle,Value);
  4310. end;
  4311.  
  4312. Procedure TCustomChartAxis.SetLabelsSeparation(Value:Integer);
  4313. Begin
  4314.   if Value<0 then
  4315.      Raise AxisException.Create(TeeMsg_AxisLabelSep);
  4316.   ParentChart.SetIntegerProperty(FLabelsSeparation,Value);
  4317. end;
  4318.  
  4319. Procedure TCustomChartAxis.SetLabelsSize(Value:Integer);
  4320. Begin
  4321.   ParentChart.SetIntegerProperty(FLabelsSize,Value);
  4322. end;
  4323.  
  4324. Procedure TCustomChartAxis.SetTitleSize(Value:Integer);
  4325. Begin
  4326.   ParentChart.SetIntegerProperty(FTitleSize,Value);
  4327. end;
  4328.  
  4329. Procedure TCustomChartAxis.SetLabelsOnAxis(Value:Boolean);
  4330. Begin
  4331.   ParentChart.SetBooleanProperty(FLabelsOnAxis,Value);
  4332. end;
  4333.  
  4334. Procedure TCustomChartAxis.SetExactDateTime(Value:Boolean);
  4335. begin
  4336.   ParentChart.SetBooleanProperty(FExactDateTime,Value);
  4337. end;
  4338.  
  4339. Procedure TCustomChartAxis.SetLabelStyle(Value:TAxisLabelStyle);
  4340. begin
  4341.   if FLabelStyle<>Value then
  4342.   begin
  4343.     FLabelStyle:=Value;
  4344.     ParentChart.Repaint;
  4345.   end;
  4346. end;
  4347.  
  4348. Procedure TCustomChartAxis.SetVisible(Value:Boolean);
  4349. Begin
  4350.   ParentChart.SetBooleanProperty(FVisible,Value);
  4351. end;
  4352.  
  4353. Procedure TCustomChartAxis.SetDesiredIncrement(Const Value:Double);
  4354. Begin
  4355.   if Value<0 then Raise AxisException.Create(TeeMsg_AxisIncrementNeg);
  4356.   if IsDateTime then DateTimeToStr(Value);
  4357.   ParentChart.SetDoubleProperty(FDesiredIncrement,Value);
  4358. end;
  4359.  
  4360. Procedure TCustomChartAxis.SetMinimum(Const Value:Double);
  4361. Begin
  4362.   if (not (csReading in ParentChart.ComponentState)) and
  4363.      (Value>FMaximumValue) then
  4364.        Raise AxisException.Create(TeeMsg_AxisMinMax);
  4365.   InternalSetMinimum(Value);
  4366. end;
  4367.  
  4368. Procedure TCustomChartAxis.InternalSetMinimum(Const Value:Double);
  4369. Begin
  4370.   ParentChart.SetDoubleProperty(FMinimumValue,Value);
  4371. end;
  4372.  
  4373. Procedure TCustomChartAxis.SetMaximum(Const Value:Double);
  4374. Begin
  4375.   if (not (csReading in ParentChart.ComponentState)) and
  4376.      (Value<FMinimumValue) then
  4377.        Raise AxisException.Create(TeeMsg_AxisMaxMin);
  4378.   InternalSetMaximum(Value);
  4379. end;
  4380.  
  4381. Procedure TCustomChartAxis.SetMinMax(Const AMin,AMax:Double);
  4382. Begin
  4383.   FAutomatic:=False;
  4384.   FAutomaticMinimum:=False;
  4385.   FAutomaticMaximum:=False;
  4386.   if AMin<=AMax then
  4387.   Begin
  4388.     InternalSetMinimum(AMin);
  4389.     InternalSetMaximum(AMax);
  4390.   End
  4391.   else
  4392.   Begin
  4393.     InternalSetMinimum(AMax);
  4394.     InternalSetMaximum(AMin);
  4395.   End;
  4396.   if (FMaximumValue-FMinimumValue)<MinAxisRange then
  4397.      InternalSetMaximum(FMinimumValue+MinAxisRange);
  4398. end;
  4399.  
  4400. Procedure TCustomChartAxis.InternalSetMaximum(Const Value:Double);
  4401. Begin
  4402.   ParentChart.SetDoubleProperty(FMaximumValue,Value);
  4403. end;
  4404.  
  4405. Procedure TCustomChartAxis.SetTickLength(Value:Integer);
  4406. Begin
  4407.   ParentChart.SetIntegerProperty(FTickLength,Value);
  4408. end;
  4409.  
  4410. Procedure TCustomChartAxis.SetMinorTickLength(Value:Integer);
  4411. Begin
  4412.   ParentChart.SetIntegerProperty(FMinorTickLength,Value);
  4413. end;
  4414.  
  4415. Procedure TCustomChartAxis.SetMinorTickCount(Value:Integer);
  4416. Begin
  4417.   ParentChart.SetIntegerProperty(FMinorTickCount,Value);
  4418. End;
  4419.  
  4420. Procedure TCustomChartAxis.SetTickInnerLength(Value:Integer);
  4421. Begin
  4422.   ParentChart.SetIntegerProperty(FTickInnerLength,Value);
  4423. end;
  4424.  
  4425. Procedure TCustomChartAxis.DrawTitle(x,y:Longint);
  4426. begin
  4427.   With ParentChart,Canvas do
  4428.   if Printing and (Font.Color=clWhite) then Font.Color:=clBlack;
  4429.   With FAxisTitle do
  4430.   if IsDepthAxis then
  4431.   With ParentChart,Canvas do
  4432.   begin
  4433.     TextAlign:=TA_LEFT;
  4434.     TextOut3D(x,y,Width3D div 2,FCaption);
  4435.   end
  4436.   else DrawAxisLabel(x,y,FAngle,FCaption);
  4437. end;
  4438.  
  4439. procedure TCustomChartAxis.DrawAxisLabel(x,y,Angle:Integer; Const St:String);
  4440. Const Aligns:Array[Boolean,Boolean] of Integer=
  4441.         ( { vertical }   (TA_RIGHT +TA_TOP, TA_LEFT  +TA_TOP    ),
  4442.           { horizontal } (TA_CENTER+TA_TOP, TA_CENTER+TA_BOTTOM )
  4443.         );
  4444.  
  4445.  
  4446. var Delta    : Integer;
  4447.     t        : Integer;
  4448.     n        : Integer;
  4449.     i        : Integer;
  4450.     tmpZ     : Integer;
  4451.     tmpSt    : String;
  4452.     tmpSt2   : String;
  4453.     tmpH     : Integer;
  4454.     tmpD     : Integer;
  4455.     tmpAlign : TCanvasTextAlign;
  4456. begin
  4457.   tmpH:=(ParentChart.Canvas.FontHeight div 2);
  4458.   Case Angle of
  4459.     0: Begin
  4460.          tmpAlign:=Aligns[Horizontal,OtherSide];
  4461.          if not Horizontal then Dec(Y,tmpH);
  4462.        end;
  4463.    90: Begin
  4464.          if Horizontal then
  4465.          begin
  4466.            tmpAlign:=Aligns[False,OtherSide];
  4467.            Dec(X,tmpH);
  4468.          end
  4469.          else tmpAlign:=Aligns[True,not OtherSide];
  4470.        end;
  4471.   180: Begin
  4472.          tmpAlign:=Aligns[Horizontal,not OtherSide];
  4473.          if not Horizontal then Inc(Y,tmpH);
  4474.        end;
  4475.   270: Begin
  4476.          if Horizontal then
  4477.          begin
  4478.            tmpAlign:=Aligns[False,not OtherSide];
  4479.            Inc(X,tmpH);
  4480.          end
  4481.          else tmpAlign:=Aligns[True,OtherSide];
  4482.        end;
  4483.     else tmpAlign:=TA_LEFT; { non-supported angles }
  4484.   end;
  4485.   With ParentChart.Canvas do
  4486.   begin
  4487.     if OtherSide then tmpZ:=ParentChart.Width3D
  4488.                  else tmpZ:=0;
  4489.     TextAlign:=tmpAlign;
  4490.     n:=TeeNumTextLines(St);
  4491.     Delta:=FontHeight;
  4492.     if (Angle=180) or (Angle=270) then Delta:=-Delta;
  4493.  
  4494.     tmpD:=Round(Delta*n);
  4495.     if Horizontal then
  4496.     begin
  4497.       if Angle=0 then
  4498.          if OtherSide then y:=y-tmpD else y:=y-Delta
  4499.       else
  4500.       if Angle=180 then
  4501.          if OtherSide then y:=y-Delta else y:=y-tmpD
  4502.       else
  4503.       if (Angle=90) or (Angle=270) then
  4504.          x:=x-Round(0.5*Delta*(n+1));
  4505.     end
  4506.     else
  4507.       if (Angle=0) or (Angle=180) then
  4508.          y:=y-Round(0.5*Delta*(n+1))
  4509.       else
  4510.       if OtherSide then
  4511.       begin
  4512.          if Angle=90 then x:=x-Delta
  4513.                      else if Angle=270 then x:=x-tmpD
  4514.       end
  4515.       else
  4516.       if Angle=90 then x:=x-tmpD
  4517.                   else if Angle=270 then x:=x-Delta;
  4518.  
  4519.     tmpSt:=St;
  4520.     for t:=1 to n do
  4521.     begin
  4522.       i:=AnsiPos(TeeLineSeparator,tmpSt);
  4523.       if i>0 then tmpSt2:=Copy(tmpSt,1,i-1) else tmpSt2:=tmpSt;
  4524.       if Angle=0 then
  4525.       begin
  4526.         y:=y+Delta;
  4527.         TextOut3D(X,Y,tmpZ,tmpSt2);
  4528.       end
  4529.       else
  4530.       begin
  4531.         if Angle=180 then y:=y+Delta
  4532.         else
  4533.         if (Angle=90) or (Angle=270) then x:=x+Delta;
  4534.         RotateLabel3D(X,Y,tmpZ,tmpSt2,Angle);
  4535.       end;
  4536.       Delete(tmpSt,1,i);
  4537.     end;
  4538.     TextAlign:=TA_LEFT;
  4539.   end;
  4540. end;
  4541.  
  4542. Procedure TCustomChartAxis.Scroll(Const Offset:Double; CheckLimits:Boolean);
  4543. Begin
  4544.   if (not CheckLimits) or
  4545.      ( ((Offset>0) and (FMaximumValue<ParentChart.InternalMinMax(Self,False,Horizontal))) or
  4546.        ((Offset<0) and (FMinimumValue>ParentChart.InternalMinMax(Self,True,Horizontal)))
  4547.      ) then
  4548.   begin
  4549.     FAutomatic:=False;
  4550.     FAutomaticMaximum:=False;
  4551.     FMaximumValue:=FMaximumValue+Offset;
  4552.     FAutomaticMinimum:=False;
  4553.     FMinimumValue:=FMinimumValue+Offset;
  4554.     ParentChart.Repaint;
  4555.   end;
  4556. end;
  4557.  
  4558. Function TCustomChartAxis.InternalCalcLog(Var LogMax,LogMin:Double):Double;
  4559. Begin
  4560.   if IMinimum<=0 then LogMin:=0 else LogMin:=ln(IMinimum);
  4561.   if IMaximum<=0 then LogMax:=0 else LogMax:=ln(IMaximum);
  4562.   result:=LogMax-LogMin;
  4563. end;
  4564.  
  4565. Function TCustomChartAxis.InternalCalcDepthPosValue(Const Value:Double):Longint;
  4566. var tmp:Double;
  4567. begin
  4568.   With ParentChart do
  4569.   if IRange=0 then result:=Width3D div 2
  4570.   else
  4571.   begin
  4572.     if FInverted then tmp:=IMaximum-Value
  4573.                  else tmp:=Value-IMinimum;
  4574.     result:=Round(1.0*Width3D*tmp/IRange);
  4575.   end;
  4576. end;
  4577.  
  4578. Function TCustomChartAxis.InternalCalcLogPosValue(IsX:Boolean; Const Value:Double):Longint;
  4579. var tmp      : Double;
  4580.     tmpValue : Double;
  4581.     LogMax   : Double;
  4582.     LogMin   : Double;
  4583. begin
  4584.   tmp:=InternalCalcLog(LogMax,LogMin);
  4585.   if tmp=0 then result:=ICenterPos
  4586.   else
  4587.   begin
  4588.     if Value<=0 then
  4589.        if (IsX and FInverted) or
  4590.           ((not IsX) and (not FInverted)) then result:=IEndPos
  4591.                                           else result:=IStartPos
  4592.     else
  4593.     begin
  4594.       if FInverted then tmpValue:=LogMax-ln(Value)
  4595.                    else tmpValue:=ln(Value)-LogMin;
  4596.       if IsX then result:=IStartPos+Round(tmpValue*IAxisSize/tmp)
  4597.              else result:=IEndPos-Round(tmpValue*IAxisSize/tmp);
  4598.     end;
  4599.   end;
  4600. end;
  4601.  
  4602. Function TCustomChartAxis.CalcPosValue(Const Value:Double):Longint;
  4603. begin
  4604.   if Horizontal then result:=CalcXPosValue(Value)
  4605.                 else result:=CalcYPosValue(Value);
  4606. end;
  4607.  
  4608. Function TCustomChartAxis.CalcXPosValue(Const Value:Double):Longint;
  4609. begin
  4610.   if IsDepthAxis then result:=InternalCalcDepthPosValue(Value) else
  4611.   if FLogarithmic then result:=InternalCalcLogPosValue(True,Value)
  4612.                   else result:=InternalCalcPosValue(Value,FInverted);
  4613. end;
  4614.  
  4615. Function TCustomChartAxis.InternalCalcPosValue( Const Value:Double;
  4616.                                                 FromEnd:Boolean):Longint;
  4617. var tmp : Double;
  4618. begin
  4619.   if IRange=0 then result:=ICenterPos
  4620.   else
  4621.   begin
  4622.     tmp:=(Value-IMinimum)*IAxisSize/IRange;
  4623.     if Abs(tmp)>=MaxLongint then
  4624.        result:=ICenterPos
  4625.     else
  4626.        if FromEnd then result:=IEndPos-Round(tmp)
  4627.                   else result:=IStartPos+Round(tmp)
  4628.   end;
  4629. end;
  4630.  
  4631. Function TCustomChartAxis.CalcYPosValue(Const Value:Double):Longint;
  4632. begin
  4633.   if IsDepthAxis then result:=InternalCalcDepthPosValue(Value) else
  4634.   if FLogarithmic then result:=InternalCalcLogPosValue(False,Value)
  4635.                   else result:=InternalCalcPosValue(Value,not FInverted);
  4636. end;
  4637.  
  4638. Function TCustomChartAxis.CalcSizeValue(Const Value:Double):Longint;
  4639. var tmp    : Double;
  4640.     LogMax : Double;
  4641.     LogMin : Double;
  4642. begin
  4643.   result:=0;
  4644.   if Value>0 then
  4645.     if FLogarithmic then
  4646.     Begin
  4647.       tmp:=InternalCalcLog(LogMax,LogMin);
  4648.       if tmp<>0 then result:=Round(ln(Value)*IAxisSize/tmp);
  4649.     end
  4650.     else
  4651.     if IRange<>0 then result:=Round(Value*IAxisSize/IRange);
  4652. end;
  4653.  
  4654. Function TCustomChartAxis.Clicked(x,y:Integer):Boolean;
  4655. Var tmpPos1 : Integer;
  4656.     Pos1    : Integer;
  4657.     tmpPos2 : Integer;
  4658.     Pos2    : Integer;
  4659.     tmpR    : TRect;
  4660. Begin
  4661.   if ParentChart.IsAxisVisible(Self) then
  4662.   begin
  4663.     if IStartPos>IEndPos then
  4664.     begin
  4665.       tmpPos1:=IEndPos;
  4666.       tmpPos2:=IStartPos;
  4667.     end
  4668.     else
  4669.     begin
  4670.       tmpPos1:=IStartPos;
  4671.       tmpPos2:=IEndPos;
  4672.     end;
  4673.  
  4674.     if PosAxis>FPosLabels then
  4675.     begin
  4676.       Pos1:=FPosLabels;
  4677.       Pos2:=PosAxis+TeeAxisClickGap;
  4678.     end
  4679.     else
  4680.     begin
  4681.       Pos1:=PosAxis-TeeAxisClickGap;
  4682.       Pos2:=FPosLabels;
  4683.     end;
  4684.  
  4685.     if Horizontal then tmpR:=Rect(tmpPos1,Pos1,tmpPos2,Pos2)
  4686.                   else tmpR:=Rect(Pos1,tmpPos1,Pos2,tmpPos2);
  4687.     result:=PtInRect(tmpR,Point(x,y));
  4688.   end
  4689.   else result:=False;
  4690. end;
  4691.  
  4692. Procedure TCustomChartAxis.CustomDrawMinMaxStartEnd( APosLabels,
  4693.                                                      APosTitle,
  4694.                                                      APosAxis:Integer;
  4695.                                                      GridVisible:Boolean;
  4696.                                                      Const AMinimum,AMaximum,
  4697.                                                            AIncrement:Double;
  4698.                                                      AStartPos,AEndPos:Integer);
  4699.  
  4700.   Procedure SetInternals;
  4701.   begin
  4702.     IMaximum :=FMaximumValue;
  4703.     IMinimum :=FMinimumValue;
  4704.     IRange   :=IMaximum-IMinimum;
  4705.   end;
  4706.  
  4707. var OldMin       : Double;
  4708.     OldMax       : Double;
  4709.     OldIncrement : Double;
  4710.     OldAutomatic : Boolean;
  4711. begin
  4712.   OldMin      :=FMinimumValue;
  4713.   OldMax      :=FMaximumValue;
  4714.   OldIncrement:=FDesiredIncrement;
  4715.   OldAutomatic:=FAutomatic;
  4716.   try
  4717.     FAutomatic       :=False;
  4718.     FMinimumValue    :=AMinimum;
  4719.     FMaximumValue    :=AMaximum;
  4720.     FDesiredIncrement:=AIncrement;
  4721.     SetInternals;
  4722.     CustomDrawStartEnd(APosLabels,APosTitle,APosAxis,GridVisible,AStartPos,AEndPos);
  4723.   finally
  4724.     FMinimumValue    :=OldMin;
  4725.     FMaximumValue    :=OldMax;
  4726.     FDesiredIncrement:=OldIncrement;
  4727.     FAutomatic       :=OldAutomatic;
  4728.     SetInternals;
  4729.   end;
  4730. end;
  4731.  
  4732. Procedure TCustomChartAxis.CustomDrawMinMax( APosLabels,
  4733.                                              APosTitle,
  4734.                                              APosAxis:Integer;
  4735.                                              GridVisible:Boolean;
  4736.                                              Const AMinimum,AMaximum,
  4737.                                                    AIncrement:Double);
  4738. begin
  4739.   CustomDrawMinMaxStartEnd(APosLabels,APosTitle,APosAxis,GridVisible,
  4740.         AMinimum,AMaximum,AIncrement,IStartPos,IEndPos);
  4741. end;
  4742.  
  4743. Procedure TCustomChartAxis.CustomDraw( APosLabels,APosTitle,APosAxis:Integer;
  4744.                                        GridVisible:Boolean);
  4745. begin
  4746.   InternalCalcPositions;
  4747.   CustomDrawStartEnd(APosLabels,APosTitle,APosAxis,GridVisible,IStartPos,IEndPos);
  4748. End;
  4749.  
  4750. Procedure TCustomChartAxis.CustomDrawStartEnd( APosLabels,APosTitle,APosAxis:Integer;
  4751.                                                GridVisible:Boolean; AStartPos,AEndPos:Integer);
  4752. var OldGridVisible : Boolean;
  4753.     OldChange      : TNotifyEvent;
  4754. Begin
  4755.   FPosLabels:=APosLabels;
  4756.   FPosTitle :=APosTitle;
  4757.   FPosAxis  :=APosAxis;
  4758.   IStartPos :=AStartPos;
  4759.   IEndPos   :=AEndPos;
  4760.   RecalcSizeCenter;
  4761.   OldGridVisible:=FGrid.Visible;
  4762.   OldChange:=FGrid.OnChange;
  4763.   FGrid.OnChange:=nil;
  4764.   FGrid.Visible:=GridVisible;
  4765.   Draw(False);
  4766.   FGrid.Visible:=OldGridVisible;
  4767.   FGrid.OnChange:=OldChange;
  4768. end;
  4769.  
  4770. Procedure TCustomChartAxis.RecalcSizeCenter;
  4771. begin
  4772.   IAxisSize:=IEndPos-IStartPos;
  4773.   ICenterPos:=(IStartPos+IEndPos) div 2;
  4774. end;
  4775.  
  4776. Procedure TCustomChartAxis.InternalCalcPositions;
  4777.  
  4778.   Procedure DoCalculation(AStartPos:Integer; ASize:Integer);
  4779.   begin
  4780.     IStartPos:=AStartPos+Round(0.01*ASize*FStartPosition);
  4781.     IEndPos  :=AStartPos+Round(0.01*ASize*FEndPosition);
  4782.   end;
  4783.  
  4784. begin
  4785.   With ParentChart do
  4786.   if Horizontal then DoCalculation(ChartRect.Left,ChartWidth)
  4787.                 else DoCalculation(ChartRect.Top,ChartHeight);
  4788.   RecalcSizeCenter;
  4789. end;
  4790.  
  4791. Function TCustomChartAxis.ApplyPosition(APos:Integer; Const R:TRect):Integer;
  4792. Var tmpSize:Integer;
  4793. begin
  4794.   result:=APos;
  4795.   if FPositionPercent<>0 then
  4796.   With R do
  4797.   begin
  4798.     if Horizontal then tmpSize:=Bottom-Top else tmpSize:=Right-Left;
  4799.     tmpSize:=Round(0.01*FPositionPercent*tmpSize);
  4800.     if OtherSide then tmpSize:=-tmpSize;
  4801.     if Horizontal then tmpSize:=-tmpSize;
  4802.     result:=APos+tmpSize;
  4803.   end;
  4804. end;
  4805.  
  4806. Function TCustomChartAxis.GetRectangleEdge(Const R:TRect):Integer;
  4807. begin
  4808.   With R do
  4809.   if OtherSide then
  4810.      if Horizontal then result:=Top else result:=Right
  4811.   else
  4812.      if Horizontal then result:=Bottom else result:=Left;
  4813. end;
  4814.  
  4815. Procedure TCustomChartAxis.Draw(CalcPosAxis:Boolean);
  4816. Var OldPosTick  : Longint;
  4817.     tmpWallSize : Longint;
  4818.     tmpValue    : Double;
  4819.  
  4820.   Procedure InternalDrawTick(tmp,Delta,tmpTickLength:Longint);
  4821.   var tmpA : Longint;
  4822.       tmpB : Longint;
  4823.   Begin
  4824.     with ParentChart do
  4825.     Begin
  4826.       if IsDepthAxis then
  4827.          Canvas.HorizLine3D(PosAxis+Delta,PosAxis+Delta+tmpTickLength,ChartRect.Bottom,tmp)
  4828.       else
  4829.       if OtherSide then
  4830.       Begin
  4831.         if Horizontal then
  4832.            Canvas.VertLine3D(tmp,PosAxis-Delta,PosAxis-Delta-tmpTickLength,Width3D)
  4833.         else
  4834.            Canvas.HorizLine3D(PosAxis+Delta,PosAxis+Delta+tmpTickLength,tmp,Width3D)
  4835.       end
  4836.       else
  4837.       begin
  4838.         tmpA:=Delta;
  4839.         Inc(tmpA,tmpWallSize);
  4840.         tmpB:=tmpA+tmpTickLength;
  4841.         if Horizontal then Canvas.VertLine3D(tmp,PosAxis+tmpA,PosAxis+tmpB,0)
  4842.                       else Canvas.HorizLine3D(PosAxis-tmpA,PosAxis-tmpB,tmp,0);
  4843.       end;
  4844.     end;
  4845.   end;
  4846.  
  4847.   Procedure DrawGrid(tmp:Longint);
  4848.   Begin
  4849.     With ParentChart,Canvas,ChartRect do
  4850.     begin
  4851.       Brush.Style:=bsClear;
  4852.       BackMode:=cbmTransparent;
  4853.       AssignVisiblePen(FGrid);
  4854.       CheckPenWidth(Pen);
  4855.       if Pen.Color=clTeeColor then Pen.Color:=clGray;
  4856.       if IsDepthAxis then
  4857.       begin
  4858.         VertLine3D(Left,Top,Bottom,tmp);
  4859.         HorizLine3D(Left,Right,Bottom,tmp);
  4860.       end
  4861.       else
  4862.       if Horizontal then
  4863.       Begin
  4864.         if View3D then
  4865.         Begin
  4866.           if OtherSide then
  4867.           begin
  4868.             VertLine3D(tmp,Top,Bottom,Width3D)
  4869.           end
  4870.           else
  4871.           begin
  4872.             if TeeDrawAxisBeforeSeries then
  4873.             begin
  4874.               ZLine3D(tmp,PosAxis,0,Width3D);
  4875.               VertLine3D(tmp,Top,Bottom,Width3D);
  4876.             end
  4877.             else VertLine3D(tmp,Top,Bottom,0);
  4878.           end;
  4879.         end
  4880.         else
  4881.         DoVertLine(tmp,Top,Bottom);
  4882.       end
  4883.       else
  4884.       Begin
  4885.         if View3D then
  4886.         Begin
  4887.           if OtherSide then
  4888.           begin
  4889.             HorizLine3D(Left,Right,tmp,Width3D);
  4890.           end
  4891.           else
  4892.           begin
  4893.             if TeeDrawAxisBeforeSeries then
  4894.             begin
  4895.               ZLine3D(PosAxis,tmp,0,Width3D);
  4896.               HorizLine3D(Left,Right,tmp,Width3D);
  4897.             end
  4898.             else HorizLine3D(Left,Right,tmp,0);
  4899.           end;
  4900.         end
  4901.         else
  4902.         DoHorizLine(Left,Right,tmp);
  4903.       end;
  4904.       BackMode:=cbmOPAQUE;
  4905.     end;
  4906.   end;
  4907.  
  4908.   Procedure DrawLabel(Const tmpSt:String; tmp:Longint);
  4909.   var tmpPosLabels : Integer;
  4910.   Begin
  4911.     With ParentChart,Canvas do
  4912.     Begin
  4913.       FontCanvas(LabelsFont);
  4914.       Brush.Color:=ParentChart.Color;
  4915.       Brush.Style:=bsClear;
  4916.       if Printing and (Font.Color=clWhite) then Font.Color:=clBlack;
  4917.       tmpPosLabels:=PosLabels;
  4918.       if IsDepthAxis then
  4919.       begin
  4920.         TextAlign:=ta_Left;
  4921.         TextOut3D(tmpPosLabels,ChartRect.Bottom,tmp,tmpSt);
  4922.       end
  4923.       else
  4924.       begin
  4925.         if Horizontal then DrawAxisLabel(tmp,tmpPosLabels,FLabelsAngle,tmpSt)
  4926.                       else DrawAxisLabel(tmpPosLabels,tmp,FLabelsAngle,tmpSt);
  4927.       end;
  4928.     end;
  4929.   end;
  4930.  
  4931.   Procedure DrawTicksGrid(tmp:Longint);
  4932.   Var t        : Longint;
  4933.       tmpDelta : Double;
  4934.   Begin
  4935.     if FTicks.Visible then
  4936.     begin
  4937.       ParentChart.Canvas.Pen.Assign(FTicks);
  4938.       InternalDrawTick(tmp,1,FTickLength);
  4939.     end;
  4940.     if FGrid.Visible {and
  4941.        ( (tmpValue<>IMaximum) and (tmpValue<>IMinimum) )} then
  4942.        if FGridCentered then
  4943.        begin
  4944.          if OldPosTick>-1 then DrawGrid(Round(0.5*(tmp+OldPosTick)))
  4945.        end
  4946.        else DrawGrid(tmp);
  4947.     if FTicksInner.Visible then
  4948.     begin
  4949.       ParentChart.Canvas.Pen.Assign(FTicksInner);
  4950.       InternalDrawTick(tmp,-1,-FTickInnerLength);
  4951.     end;
  4952.     if FMinorTicks.Visible and (OldPosTick>-1) then
  4953.     Begin
  4954.       ParentChart.Canvas.Pen.Assign(FMinorTicks);
  4955.       if not FLogarithmic then
  4956.       begin
  4957.         tmpDelta:=1.0*(tmp-OldPosTick)/(FMinorTickCount+1);
  4958.         for t:=1 to FMinorTickCount do
  4959.             InternalDrawTick(tmp-Round(t*tmpDelta),1,FMinorTickLength);
  4960.       end;
  4961.     end;
  4962.     OldPosTick:=tmp;
  4963.   end;
  4964.  
  4965.   Procedure DrawThisLabel(LabelPos:Longint; Const tmpSt:String);
  4966.   begin
  4967.     if TickOnLabelsOnly then DrawTicksGrid(LabelPos);
  4968.     DrawLabel(tmpSt,LabelPos);
  4969.   end;
  4970.  
  4971. Var tmpLabelStyle : TAxisLabelStyle;
  4972.     tmpSeriesList : TList;
  4973.  
  4974.   Function GetAxisSeriesLabel(AIndex:Longint; Var AValue:Double;
  4975.                               Var ALabel:String):Boolean;
  4976.   var t:Integer;
  4977.   begin
  4978.     result:=False;
  4979.     for t:=0 to tmpSeriesList.Count-1 do
  4980.     With TChartSeries(tmpSeriesList[t]) do
  4981.     if FXLabels.Count>AIndex then
  4982.     begin
  4983.       Case tmpLabelStyle of
  4984.         talMark : ALabel:=ValueMarkText[AIndex];
  4985.         talText : ALabel:=XLabel[AIndex];
  4986.       end;
  4987.       if Assigned(ParentChart.FOnGetAxisLabel) then
  4988.          ParentChart.FOnGetAxisLabel( TChartAxis(Self),
  4989.                          TChartSeries(tmpSeriesList[t]),AIndex,ALabel);
  4990.       AValue:=GetValue(Horizontal,AIndex);
  4991.       result:=True;
  4992.       break;
  4993.     end;
  4994.   end;
  4995.  
  4996.   { Select all active Series that have "Labels" }
  4997.   Procedure CalcAllSeries;
  4998.   var t:Integer;
  4999.   begin
  5000.     tmpSeriesList.Clear;
  5001.     With ParentChart do
  5002.     for t:=0 to SeriesList.Count-1 do
  5003.     With Series[t] do
  5004.     if Active and AssociatedToAxis(Self) then
  5005.     begin
  5006. {   FIXED BUG 4.0:   ** "If" commented **
  5007.       if (Horizontal and YMandatory) or
  5008.         ((not Horizontal) and (not YMandatory)) then }
  5009.         if FXLabels.Count>0 then
  5010.            tmpSeriesList.Add(Series[t]);
  5011.     end;
  5012.   end;
  5013.  
  5014.   Procedure CalcFirstLastAllSeries(Var tmpFirst,tmpLast:Longint);
  5015.   var t:Integer;
  5016.   begin
  5017.     tmpFirst:=-1;
  5018.     tmpLast:=-1;
  5019.     for t:=0 to tmpSeriesList.Count-1 do
  5020.     With TChartSeries(tmpSeriesList[t]) do
  5021.     begin
  5022.       CalcFirstLastVisibleIndex;
  5023.       if (tmpFirst=-1) or (tmpFirst>FFirstVisibleIndex) then
  5024.          tmpFirst:=FFirstVisibleIndex;
  5025.       if (tmpLast=-1) or (tmpLast<FLastVisibleIndex) then
  5026.          tmpLast:=FLastVisibleIndex;
  5027.     end;
  5028.   end;
  5029.  
  5030.   Procedure AxisLabelsSeries;
  5031.   Var t            : Longint;
  5032.       tmp          : Longint;
  5033.       tmpNum       : Integer;
  5034.       tmpFirst     : Longint;
  5035.       tmpLast      : Longint;
  5036.       tmpSt        : String;
  5037.       tmpValue     : Double;
  5038.       OldPosLabel  : Longint;
  5039.       OldSizeLabel : Longint;
  5040.       tmpLabelSize : Integer;
  5041.       tmpDraw      : Boolean;
  5042.       tmpLabelW    : Boolean;
  5043.   Begin
  5044.     tmpSeriesList:=TList.Create;
  5045.     CalcAllSeries;
  5046.     CalcFirstLastAllSeries(tmpFirst,tmpLast);
  5047.  
  5048.     if tmpFirst<>-1 then
  5049.     begin
  5050.       OldPosLabel :=-1;
  5051.       OldSizeLabel:= 0;
  5052.       tmpLabelW:=Horizontal;
  5053.       Case FLabelsAngle of
  5054.          90,270: tmpLabelW:=not tmpLabelW;
  5055.       end;
  5056.       for t:=tmpFirst to tmpLast do
  5057.       Begin
  5058.         if GetAxisSeriesLabel(t,tmpValue,tmpSt) then
  5059.         begin
  5060.           if (tmpValue>=IMinimum) and (tmpValue<=IMaximum) then
  5061.           begin
  5062.             if Horizontal then tmp:=Self.CalcXPosValue(tmpValue)
  5063.                           else tmp:=Self.CalcYPosValue(tmpValue);
  5064.             if not TickOnLabelsOnly then DrawTicksGrid(tmp);
  5065.             if FLabels then
  5066.             begin
  5067.               With ParentChart.Canvas do
  5068.               begin
  5069.                 { fixed 4.01 }
  5070.                 tmpLabelSize:=ParentChart.MultiLineTextWidth(tmpSt,tmpNum);
  5071.                 if not tmpLabelW then tmpLabelSize:=FontHeight*tmpNum;
  5072.               end;
  5073.               if (FLabelsSeparation<>0) and (OldPosLabel<>-1) then
  5074.               begin
  5075.                 Inc(tmpLabelSize,Trunc(0.02*tmpLabelSize*FLabelsSeparation));
  5076.                 tmpLabelSize:=tmpLabelSize div 2;
  5077.  
  5078.                 if tmp>=OldPosLabel then
  5079.                    tmpDraw:=(tmp-tmpLabelSize)>=(OldPosLabel+OldSizeLabel)
  5080.                 else
  5081.                    tmpDraw:=(tmp+tmpLabelSize)<=(OldPosLabel-OldSizeLabel);
  5082.                 if tmpDraw then
  5083.                 begin { fixed 4.01 }
  5084.                   DrawThisLabel(tmp,tmpSt);
  5085.                   OldPosLabel:=tmp;
  5086.                   OldSizeLabel:=tmpLabelSize;
  5087.                 end;
  5088.               end
  5089.               else
  5090.               begin { fixed 4.01 }
  5091.                 DrawThisLabel(tmp,tmpSt);
  5092.                 OldPosLabel:=tmp;
  5093.                 OldSizeLabel:=tmpLabelSize div 2;
  5094.               end;
  5095.             end;
  5096.           end;
  5097.         end;
  5098.       end;
  5099.     end;
  5100.     tmpSeriesList.Free;
  5101.   end;
  5102.  
  5103. var IIncrement       : Double;
  5104.     tmpWhichDateTime : TDateTimeStep;
  5105.  
  5106.   Procedure InternalDrawLabel(DecValue:Boolean);
  5107.   var tmp : Longint;
  5108.   Begin
  5109.     if Horizontal then tmp:=CalcXPosValue(tmpValue)
  5110.                   else tmp:=CalcYPosValue(tmpValue);
  5111.     if not TickOnLabelsOnly then DrawTicksGrid(tmp);
  5112.     if FLabels then DrawThisLabel(tmp,LabelValue(tmpValue));
  5113.     if DecValue then IncDecDateTime(False,tmpValue,IIncrement,tmpWhichDateTime);
  5114.   end;
  5115.  
  5116.   Procedure DoDefaultLogLabels;
  5117.  
  5118.     {$IFDEF D1}
  5119.     function IntPower(Const Base: Extended; Exponent: Integer): Extended;
  5120.     var t:Integer;
  5121.     begin
  5122.       result:=Base;
  5123.       for t:=1 to Exponent do result:=result*Base;
  5124.     end;
  5125.  
  5126.     function LogBaseN(Const Base, X: Extended): Extended;
  5127.     begin
  5128.       result:=Ln(X)/Ln(Base);
  5129.     end;
  5130.     {$ELSE}
  5131.  
  5132.     { From Borland's Math.pas unit. Some Delphi and BCB
  5133.       versions do not include math.pas unit }
  5134.     function IntPower(Const Base: Extended; Exponent: Integer): Extended;
  5135.     asm
  5136.         mov     ecx, eax
  5137.         cdq
  5138.         fld1                      { Result := 1 }
  5139.         xor     eax, edx
  5140.         sub     eax, edx          { eax := Abs(Exponent) }
  5141.         jz      @@3
  5142.         fld     Base
  5143.         jmp     @@2
  5144.     @@1:    fmul    ST, ST            { X := Base * Base }
  5145.     @@2:    shr     eax,1
  5146.         jnc     @@1
  5147.         fmul    ST(1),ST          { Result := Result * X }
  5148.         jnz     @@1
  5149.         fstp    st                { pop X from FPU stack }
  5150.         cmp     ecx, 0
  5151.         jge     @@3
  5152.         fld1
  5153.         fdivrp                    { Result := 1 / Result }
  5154.     @@3:
  5155.         fwait
  5156.     end;
  5157.  
  5158.     function LogBaseN(Const Base, X: Extended): Extended;
  5159.     asm
  5160.       FLD1
  5161.       FLD     X
  5162.       FYL2X
  5163.       FLD1
  5164.       FLD     Base
  5165.       FYL2X
  5166.       FDIV
  5167.       FWAIT
  5168.     end;
  5169.     {$ENDIF}
  5170.  
  5171.   Var tmpDelta     : Double;
  5172.       tmpValueTick : Double;
  5173.       t            : Integer;
  5174.   begin
  5175.     if IMinimum<>IMaximum then
  5176.     begin
  5177.       if IMinimum<=0 then
  5178.       begin
  5179.         if IMinimum=0 then IMinimum:=0.1
  5180.                       else IMinimum:=MinAxisRange;
  5181.         tmpValue:=IMinimum;
  5182.       end
  5183.       else tmpValue:=IntPower(FLogarithmicBase,Round(LogBaseN(FLogarithmicBase,IMinimum)));
  5184.       While tmpValue<=IMaximum do
  5185.       begin
  5186.         if tmpValue>=IMinimum then
  5187.         begin
  5188.           InternalDrawLabel(False);
  5189.           if FMinorTicks.Visible then
  5190.           begin
  5191.             ParentChart.Canvas.Pen.Assign(FMinorTicks);
  5192.             tmpDelta:=((tmpValue*FLogarithmicBase)-tmpValue)/(FMinorTickCount+1);
  5193.             for t:=1 to FMinorTickCount do
  5194.             begin
  5195.               tmpValueTick:=tmpValue+(t*tmpDelta);
  5196.               if tmpValueTick>IMaximum then break
  5197.               else
  5198.                  InternalDrawTick(CalcPosValue(tmpValueTick),1,FMinorTickLength);
  5199.             end;
  5200.           end;
  5201.         end;
  5202.         tmpValue:=tmpValue*FLogarithmicBase;
  5203.       end;
  5204.     end;
  5205.   end;
  5206.  
  5207.   Procedure DoDefaultLabels;
  5208.   Begin
  5209.     tmpValue:=IMaximum/IIncrement;
  5210.     if (Abs(tmpValue)<MaxLongint) and
  5211.        (Abs(IRange/IIncrement)<10000) then
  5212.     Begin
  5213.       if IAxisDateTime and FExactDateTime and
  5214.          (tmpWhichDateTime<>dtNone) and (tmpWhichDateTime>=dtOneDay) then
  5215.              tmpValue:=TeeRoundDate(IMaximum,tmpWhichDateTime)
  5216.       else
  5217.       if (IMinimum=IMaximum) or (not RoundFirstLabel) then
  5218.          tmpValue:=IMaximum
  5219.       else
  5220.          tmpValue:=IIncrement*Trunc(tmpValue);
  5221.       if FLabelsOnAxis then
  5222.       begin
  5223.         While tmpValue>IMaximum do
  5224.               IncDecDateTime(False,tmpValue,IIncrement,tmpWhichDateTime);
  5225.         While tmpValue>=IMinimum do InternalDrawLabel(True);
  5226.       end
  5227.       else
  5228.       begin
  5229.         While tmpValue>=IMaximum do
  5230.               IncDecDateTime(False,tmpValue,IIncrement,tmpWhichDateTime);
  5231.         While tmpValue>IMinimum do InternalDrawLabel(True);
  5232.       end;
  5233.     end;
  5234.   end;
  5235.  
  5236.   Procedure DoCustomLabels;
  5237.   Const DifFloat = 0.0000001;
  5238.   var LabelIndex  : Longint;
  5239.       Stop        : Boolean;
  5240.       LabelInside : Boolean;
  5241.   Begin
  5242.     tmpValue:=IMinimum;
  5243.     Stop:=True;
  5244.     LabelIndex:=0;
  5245.     LabelInside:=False;
  5246.     Repeat
  5247.       ParentChart.FOnGetNextAxisLabel(TChartAxis(Self),LabelIndex,tmpValue,Stop);
  5248.       if Stop then
  5249.       Begin
  5250.         if LabelIndex=0 then DoDefaultLabels;
  5251.         Exit;
  5252.       end
  5253.       else
  5254.       begin { Trick with doubles... }
  5255.         LabelInside:=(tmpValue>=(IMinimum-DifFloat)) and
  5256.                      (tmpValue<=(IMaximum+DifFloat));
  5257.         if LabelInside then InternalDrawLabel(False);
  5258.         Inc(LabelIndex);
  5259.       end;
  5260.     Until Stop or (not LabelInside) or (LabelIndex>1000); { maximum 1000 labels... }
  5261.   end;
  5262.  
  5263.   Procedure DrawAxisTitle;
  5264.   begin
  5265.     With ParentChart do
  5266.     Begin
  5267.       FontCanvas(FAxisTitle.Font);
  5268.       Canvas.Brush.Color:=Color;
  5269.       Canvas.Brush.Style:=bsClear;
  5270.       if IsDepthAxis then DrawTitle(PosTitle,ChartRect.Bottom)
  5271.       else
  5272.       if Horizontal then DrawTitle(ICenterPos,PosTitle)
  5273.                     else DrawTitle(PosTitle,ICenterPos);
  5274.     end;
  5275.   end;
  5276.  
  5277.   Procedure DepthAxisLabels;
  5278.   Var t     : Longint;
  5279.       tmp   : Longint;
  5280.       tmpSt : String;
  5281.   Begin
  5282.     if ParentChart.SeriesList.CountActive>0 then
  5283.     for t:=Trunc(IMinimum) to Trunc(IMaximum) do
  5284.     Begin
  5285.       tmp:=Self.InternalCalcDepthPosValue(IMaximum-t-0.5);
  5286.       if not TickOnLabelsOnly then DrawTicksGrid(tmp);
  5287.       if FLabels then
  5288.       begin
  5289.         With ParentChart do
  5290.         begin
  5291.           tmpSt:=SeriesTitleLegend(t);
  5292.           if Assigned(FOnGetAxisLabel) then FOnGetAxisLabel(TChartAxis(Self),nil,t,tmpSt);
  5293.         end;
  5294.         DrawThisLabel(tmp,tmpSt);
  5295.       end;
  5296.     end;
  5297.   end;
  5298.  
  5299. Begin
  5300.   With ParentChart,ChartRect do
  5301.   Begin
  5302.     IAxisDateTime:=IsDateTime;
  5303.     tmpWallSize:=CalcWallSize(Self);
  5304.     FontCanvas(Self.FLabelsFont);
  5305.     IIncrement:=CalcIncrement;
  5306.     if CalcPosAxis then FPosAxis:=ApplyPosition(GetRectangleEdge(ChartRect),ChartRect);
  5307.     if FAxisTitle.FCaption<>'' then DrawAxisTitle;
  5308.  
  5309.     if IAxisDateTime and FExactDateTime and (FDesiredIncrement<>0) then
  5310.     begin
  5311.       tmpWhichDateTime:=FindDateTimeStep(FDesiredIncrement);
  5312.       if tmpWhichDateTime<>dtNone then
  5313.       While (IIncrement>DateTimeStep[tmpWhichDateTime]) and
  5314.             (tmpWhichDateTime<>dtOneYear) do
  5315.                 tmpWhichDateTime:=Succ(tmpWhichDateTime);
  5316.     end
  5317.     else tmpWhichDateTime:=dtNone;
  5318.  
  5319.     if ((IIncrement>0) or
  5320.        ( (tmpWhichDateTime>=dtHalfMonth) and (tmpWhichDateTime<=dtOneYear)) )
  5321.        and (IMaximum>=IMinimum) then
  5322.     Begin
  5323.       OldPosTick   :=-1;
  5324.       tmpLabelStyle:=CalcLabelStyle;
  5325.       Case tmpLabelStyle of
  5326.        talValue: if Assigned(FOnGetNextAxisLabel) then
  5327.                     DoCustomLabels
  5328.                  else
  5329.                  if FLogarithmic and (FDesiredIncrement=0) then
  5330.                     DoDefaultLogLabels
  5331.                  else
  5332.                     DoDefaultLabels;
  5333.         talMark: AxisLabelsSeries;
  5334.         talText: if IsDepthAxis then DepthAxisLabels else AxisLabelsSeries;
  5335.       end;
  5336.     end;
  5337.     if FAxis.Visible then
  5338.     begin
  5339.       Canvas.Pen.Assign(FAxis);
  5340.       DrawAxisLine(tmpWallSize);
  5341.     end;
  5342.   end;
  5343. end;
  5344.  
  5345. Function TCustomChartAxis.SizeTickAxis:Integer;
  5346. begin
  5347.   if FAxis.Visible then result:=FAxis.Width
  5348.                    else result:=0;
  5349.   if FTicks.Visible then result:=result+FTickLength;
  5350.   if FMinorTicks.Visible then result:=MaxLong(result,FMinorTickLength);
  5351. end;
  5352.  
  5353. Function TCustomChartAxis.SizeTitle:Integer;
  5354. begin
  5355.   With FAxisTitle do result:=InternalCalcSize(Font,FAngle,FCaption,FTitleSize);
  5356. end;
  5357.  
  5358. Function TCustomChartAxis.SizeLabels:Integer;
  5359. begin
  5360.   result:=InternalCalcSize(FLabelsFont,FLabelsAngle,'',FLabelsSize);
  5361. end;
  5362.  
  5363. Function TCustomChartAxis.InternalCalcSize( tmpFont:TFont;
  5364.                                             tmpAngle:Longint;
  5365.                                             Const tmpText:String;
  5366.                                             tmpSize:Longint):Longint;
  5367. Begin
  5368.   if tmpSize<>0 then result:=tmpSize
  5369.   else
  5370.   With ParentChart,Canvas do
  5371.   Begin
  5372.     FontCanvas(tmpFont);
  5373.     if Horizontal then
  5374.     Case tmpAngle of
  5375.       0, 180: result:=FontHeight;
  5376.     else { optimized for speed }
  5377.       if tmpText='' then result:=MaxLabelsWidth
  5378.                     else result:=Canvas.TextWidth(tmpText);
  5379.     end
  5380.     else
  5381.     Case tmpAngle of
  5382.      90, 270: result:=FontHeight;
  5383.     else { optimized for speed }
  5384.       if tmpText='' then result:=MaxLabelsWidth
  5385.                     else result:=Canvas.TextWidth(tmpText);
  5386.     end;
  5387.   end;
  5388. end;
  5389.  
  5390. Procedure TCustomChartAxis.CalcRect(Var R:TRect; InflateChartRectangle:Boolean);
  5391.  
  5392.   Procedure InflateAxisRect(Value:Longint);
  5393.   Begin
  5394.     With R do
  5395.     if Horizontal then
  5396.        if OtherSide then Inc(Top,Value) else Dec(Bottom,Value)
  5397.     else
  5398.        if OtherSide then Dec(Right,Value) else Inc(Left,Value);
  5399.   end;
  5400.  
  5401.   Function InflateAxisPos(Value:Integer; Amount:Integer):Integer;
  5402.   Begin
  5403.     result:=Value;
  5404.     if Horizontal then
  5405.        if OtherSide then Dec(result,Amount) else Inc(result,Amount)
  5406.     else
  5407.        if OtherSide then Inc(result,Amount) else Dec(result,Amount);
  5408.   end;
  5409.  
  5410.   Function CalcLabelsRect(tmpSize:Integer):Integer;
  5411.   begin
  5412.     InflateAxisRect(tmpSize);
  5413.     result:=GetRectangleEdge(R);
  5414.   end;
  5415.  
  5416. var tmp : Integer;
  5417. Begin
  5418.   IAxisDateTime:=IsDateTime;
  5419.  
  5420.   if InflateChartRectangle then
  5421.   begin
  5422.     if IsDepthAxis then
  5423.        FPosTitle:=R.Right
  5424.     else
  5425.        With FAxisTitle do
  5426.        if FCaption<>'' then FPosTitle:=CalcLabelsRect(SizeTitle);
  5427.  
  5428.     if FLabels then FPosLabels:=CalcLabelsRect(SizeLabels);
  5429.  
  5430.     tmp:=SizeTickAxis;
  5431.     Inc(tmp,ParentChart.CalcWallSize(Self));
  5432.     if tmp>0 then InflateAxisRect(tmp);
  5433.     FPosTitle:=ApplyPosition(FPosTitle,R);
  5434.     FPosLabels:=ApplyPosition(FPosLabels,R);
  5435.   end
  5436.   else
  5437.   begin
  5438.     FPosAxis:=ApplyPosition(GetRectangleEdge(R),R);
  5439.     FPosLabels:=InflateAxisPos(FPosAxis,SizeTickAxis);
  5440.     FPosTitle:=InflateAxisPos(FPosLabels,SizeLabels);
  5441.   end;
  5442. end;
  5443.  
  5444. Procedure TChartAxis.DrawAxisLine(AWallSize:Integer);
  5445. begin
  5446.   With ParentChart,Canvas do
  5447.   if Horizontal then
  5448.      if OtherSide then
  5449.         HorizLine3D(IStartPos,IEndPos,PosAxis,Width3D)
  5450.      else
  5451.         HorizLine3D(IStartPos-CalcWallSize(LeftAxis),
  5452.                     IEndPos,PosAxis+AWallSize,0)
  5453.   else
  5454.      if OtherSide then
  5455.         VertLine3D(PosAxis,IStartPos,IEndPos,Width3D)
  5456.      else
  5457.         VertLine3D(PosAxis-AWallSize,
  5458.                    IStartPos,IEndPos+CalcWallSize(BottomAxis),0);
  5459. end;
  5460.  
  5461. { TChartDepthAxis }
  5462. Procedure TChartDepthAxis.DrawAxisLine;
  5463. var tmp:Integer;
  5464. begin
  5465.   With ParentChart,ChartRect,Canvas do
  5466.   begin
  5467.     tmp:=Bottom+CalcWallSize(BottomAxis);
  5468.     MoveTo3D(Right,tmp,0);
  5469.     LineTo3D(Right,tmp,Width3D);
  5470.   end;
  5471. end;
  5472.  
  5473. { TCustomAxisPanel }
  5474. Constructor TCustomAxisPanel.Create(AOwner: TComponent);
  5475. begin
  5476.   inherited Create(AOwner);
  5477.   FAxisVisible:=True;
  5478.   FSeriesList:=TChartSeriesList.Create;
  5479.   FSeriesList.FOwner:=Self;
  5480.   FView3DWalls:=True;
  5481.  
  5482.   FClipPoints:=True;
  5483.  
  5484.   FAxes:=TList.Create;
  5485.  
  5486.   { Create axes... }
  5487.   FBottomAxis:=TChartAxis.Create(Self);
  5488.   FBottomAxis.FHorizontal:=True;
  5489.  
  5490.   FTopAxis:=TChartAxis.Create(Self);
  5491.   With FTopAxis do
  5492.   begin
  5493.     FHorizontal:=True;
  5494.     FOtherSide:=True;
  5495.   end;
  5496.  
  5497.   FLeftAxis:=TChartAxis.Create(Self);
  5498.   FLeftAxis.FAxisTitle.FAngle:=90;
  5499.   FLeftAxis.IDefaultTitleAngle:=90;
  5500.  
  5501.   FRightAxis:=TChartAxis.Create(Self);
  5502.   With FRightAxis do
  5503.   begin
  5504.     FAxisTitle.FAngle:=270;
  5505.     IDefaultTitleAngle:=270;
  5506.     FOtherSide:=True;
  5507.   end;
  5508.  
  5509.   FDepthAxis := TChartDepthAxis.Create(Self);
  5510.   With FDepthAxis do
  5511.   begin
  5512.     FVisible:=False;
  5513.     IsDepthAxis:=True;
  5514.     FOtherSide:=True;
  5515.   end;
  5516.  
  5517.   { Paging default values }
  5518.   FPage:=1;
  5519.   FScaleLastPage:=True;
  5520. end;
  5521.  
  5522. Procedure TCustomAxisPanel.SetPage(Value:Longint);
  5523. var tmp:Longint;
  5524. Begin
  5525.   { Allow "Page" to be into: >= 1 , <= NumPages }
  5526.   tmp:=NumPages;
  5527.   if Value>tmp then Value:=tmp;
  5528.   if Value<1 then Value:=1;
  5529.   if FPage<>Value then
  5530.   begin
  5531.     SetLongintProperty(FPage,Value);
  5532.     { Trigged "changed page" event }
  5533.     if Assigned(FOnPageChange) then FOnPageChange(Self);
  5534.   end;
  5535. end;
  5536.  
  5537. Procedure TCustomAxisPanel.SetScaleLastPage(Value:Boolean);
  5538. Begin
  5539.   SetBooleanProperty(FScaleLastPage,Value);
  5540. End;
  5541.  
  5542. Function TCustomAxisPanel.NumPages:Longint;
  5543.  
  5544.   Function CalcNumPages(AAxis:TChartAxis):Longint;
  5545.   var tmp       : Longint;
  5546.       t         : Integer;
  5547.       FirstTime : Boolean;
  5548.   Begin
  5549.     { By default, one single page }
  5550.     result:=1;
  5551.     { Calc max number of points for all active series
  5552.       associated to "AAxis" axis }
  5553.     tmp:=0;
  5554.     FirstTime:=True;
  5555.     for t:=0 to FSeriesList.Count-1 do
  5556.     With Series[t] do
  5557.     if FActive and AssociatedToAxis(AAxis) then
  5558.        if FirstTime or (Count>tmp) then
  5559.        begin
  5560.          tmp:=Count;
  5561.          FirstTime:=False;
  5562.        end;
  5563.     { If there are points... divide into pages... }
  5564.     if tmp>0 then
  5565.     Begin
  5566.       result:=tmp div FMaxPointsPerPage;
  5567.       { extra page for remaining points... }
  5568.       if (tmp mod FMaxPointsPerPage)>0 then Inc(result);
  5569.     end;
  5570.   end;
  5571.  
  5572. Begin
  5573.   if FMaxPointsPerPage=0 then result:=1
  5574.   else
  5575.   begin
  5576.     if FSeriesList.Count>0 then
  5577.     begin
  5578.       if Series[0].YMandatory then
  5579.          result:=MaxLong(CalcNumPages(FTopAxis),CalcNumPages(FBottomAxis))
  5580.       else
  5581.          result:=MaxLong(CalcNumPages(FLeftAxis),CalcNumPages(FRightAxis));
  5582.     end
  5583.     else result:=1;
  5584.   end;
  5585. End;
  5586.  
  5587. Procedure TCustomAxisPanel.SetMaxPointsPerPage(Value:Longint);
  5588. var tmp : Longint;
  5589. Begin
  5590.   if Value<0 then Raise ChartException.Create(TeeMsg_MaxPointsPerPage)
  5591.              else
  5592.              Begin
  5593.                SetLongintProperty(FMaxPointsPerPage,Value);
  5594.                tmp:=NumPages;
  5595.                if FPage>tmp then Page:=tmp;
  5596.              end;
  5597. end;
  5598.  
  5599. Procedure TCustomAxisPanel.FreeAllSeries;
  5600. begin
  5601.   While SeriesCount>0 do
  5602.   With Series[0] do
  5603.   begin
  5604.     ParentChart:=nil;
  5605.     Free;
  5606.   end;
  5607. end;
  5608.  
  5609. Destructor TCustomAxisPanel.Destroy;
  5610. Begin
  5611.   FreeAllSeries;
  5612.   FSeriesList.Free;
  5613.   With FAxes do
  5614.   While Count>0 do
  5615.   begin
  5616.     TChartAxis(First).Free;
  5617.     Delete(0);
  5618.   end;
  5619.   FAxes.Free;
  5620.   inherited Destroy;
  5621. end;
  5622.  
  5623. { Steps to determine if an axis is Visible:
  5624.  
  5625.   1) The global Chart.AxisVisible property is True... and...
  5626.   2) The Axis Visible property is True... and...
  5627.   3) At least there is a Series Active and associated to the axis and
  5628.      the Series has the "UseAxis" property True.
  5629. }
  5630. Function TCustomAxisPanel.IsAxisVisible(Axis:TCustomChartAxis):Boolean;
  5631. var t : Integer;
  5632. Begin
  5633.   result:=FAxisVisible and Axis.FVisible;
  5634.   if result then { if still visible... }
  5635.      if Axis.IsDepthAxis then result:=View3D
  5636.      else
  5637.      for t:=0 to FSeriesList.Count-1 do
  5638.        With Series[t] do
  5639.        if FActive and UseAxis then
  5640.        begin
  5641.          result:=AssociatedToAxis(Axis);
  5642.          if result then exit;
  5643.        end;
  5644. end;
  5645.  
  5646. Function TCustomAxisPanel.InternalMinMax(AAxis:TCustomChartAxis; IsMin,IsX:Boolean):Double;
  5647. var t             : Longint;
  5648.     tmpCount      : Longint;
  5649.     FirstTime     : Boolean;
  5650.     tmpPagingAxis : Boolean;
  5651.     tmp           : Double;
  5652.     tmpSeries     : TChartSeries;
  5653.     tmpFirstPoint : Longint;
  5654.     tmpLastPoint  : Longint;
  5655.     tmpNumPoints  : Longint;
  5656.     tt            : Integer;
  5657. Begin
  5658.   if AAxis.IsDepthAxis then
  5659.   begin
  5660.     if AAxis.CalcLabelStyle=talValue then
  5661.     begin
  5662.       result:=0;
  5663.       for tt:=0 to FSeriesList.Count-1 do
  5664.       With Series[tt] do
  5665.       if Active then
  5666.       begin
  5667.         if IsMin then result:=MinZValue else result:=MaxZValue;
  5668.         Break;
  5669.       end;
  5670.     end
  5671.     else
  5672.     if IsMin then result:=-0.5 else result:=MaxZOrder+0.5;
  5673.   end
  5674.   else
  5675.   begin
  5676.     result:=0;
  5677.     tmpSeries:=GetAxisSeries(AAxis);
  5678.     if Assigned(tmpSeries) then
  5679.     begin
  5680.       if tmpSeries.YMandatory then tmpPagingAxis:=IsX
  5681.                               else tmpPagingAxis:=not IsX;
  5682.     end
  5683.     else tmpPagingAxis:=IsX;
  5684.     if (FMaxPointsPerPage>0) and tmpPagingAxis then
  5685.     Begin
  5686.       if Assigned(tmpSeries) and (tmpSeries.Count>0) then
  5687.       Begin
  5688.         tmpFirstPoint:=(FPage-1)*FMaxPointsPerPage;
  5689.         tmpCount:=tmpSeries.Count;
  5690.         if tmpCount<=tmpFirstPoint then
  5691.            tmpFirstPoint:=MaxLong(0,(tmpCount div FMaxPointsPerPage)-1)*FMaxPointsPerPage;
  5692.         tmpLastPoint:=tmpFirstPoint+FMaxPointsPerPage-1;
  5693.         if tmpCount<=tmpLastPoint then
  5694.            tmpLastPoint:=tmpFirstPoint+(tmpCount mod FMaxPointsPerPage)-1;
  5695.         if IsMin then
  5696.            result:=tmpSeries.GetValue(IsX,tmpFirstPoint)
  5697.         else
  5698.         Begin
  5699.           result:=tmpSeries.GetValue(IsX,tmpLastPoint);
  5700.           if not FScaleLastPage then
  5701.           begin
  5702.             tmpNumPoints:=tmpLastPoint-tmpFirstPoint+1;
  5703.             if tmpNumPoints<FMaxPointsPerPage then
  5704.             begin
  5705.               tmp:=tmpSeries.GetValue(IsX,tmpFirstPoint);
  5706.               result:=tmp+FMaxPointsPerPage*(result-tmp)/tmpNumPoints;
  5707.             end;
  5708.           end;
  5709.         end;
  5710.       end;
  5711.     end
  5712.     else
  5713.     begin
  5714.       FirstTime:=True;
  5715.       for t:=0 to FSeriesList.Count-1 do
  5716.       With Series[t] do
  5717.       if FActive and (Count>0) then
  5718.       Begin
  5719.         if (      IsX  and ((HorizAxis=aBothHorizAxis) or (GetHorizAxis=AAxis)) ) or
  5720.            ( (Not IsX) and ((VertAxis=aBothVertAxis) or (GetVertAxis =AAxis)) )  then
  5721.         Begin
  5722.           if IsMin then
  5723.              if IsX then tmp:=MinXValue else tmp:=MinYValue
  5724.           else
  5725.              if IsX then tmp:=MaxXValue else tmp:=MaxYValue;
  5726.           if FirstTime or
  5727.            ( IsMin and (tmp<result) ) or
  5728.            ( (Not IsMin) and (tmp>result) ) then
  5729.           Begin
  5730.             result:=tmp;
  5731.             FirstTime:=False;
  5732.           end;
  5733.         end;
  5734.       end;
  5735.     end;
  5736.   end;
  5737. End;
  5738.  
  5739. Function TCustomAxisPanel.MaxXValue(AAxis:TChartAxis):Double;
  5740. Begin
  5741.   result:=InternalMinMax(AAxis,False,True);
  5742. end;
  5743.  
  5744. Function TCustomAxisPanel.MaxYValue(AAxis:TChartAxis):Double;
  5745. Begin
  5746.   result:=InternalMinMax(AAxis,False,False);
  5747. end;
  5748.  
  5749. Function TCustomAxisPanel.MinXValue(AAxis:TChartAxis):Double;
  5750. Begin
  5751.   result:=InternalMinMax(AAxis,True,True);
  5752. end;
  5753.  
  5754. Function TCustomAxisPanel.MinYValue(AAxis:TChartAxis):Double;
  5755. Begin
  5756.   result:=InternalMinMax(AAxis,True,False);
  5757. end;
  5758.  
  5759. Function TCustomAxisPanel.ActiveSeriesLegend(ItemIndex:Longint):TChartSeries;
  5760. var t   : Integer;
  5761.     tmp : Longint;
  5762. begin
  5763.   tmp:=0;
  5764.   for t:=0 to FSeriesList.Count-1 do
  5765.   With Series[t] do
  5766.   if Active and ShowInLegend then
  5767.      if tmp=ItemIndex then
  5768.      begin
  5769.        result:=Series[t];
  5770.        exit;
  5771.      end
  5772.      else Inc(tmp);
  5773.   result:=nil;
  5774. end;
  5775.  
  5776. Function TCustomAxisPanel.SeriesTitleLegend(SeriesIndex:Longint):String;
  5777. var tmpSeries : TChartSeries;
  5778. Begin
  5779.   tmpSeries:=ActiveSeriesLegend(SeriesIndex);
  5780.   if Assigned(tmpSeries) then
  5781.   with tmpSeries do
  5782.   Begin
  5783.     if FTitle='' then
  5784.     Begin
  5785.       result:=Name;
  5786.       if result='' then result:='Series '+IntToStr(SeriesIndex); { <-- do not translate }
  5787.     end
  5788.     else result:=FTitle;
  5789.   end
  5790.   else result:='';
  5791. end;
  5792.  
  5793. Function TCustomAxisPanel.MaxTextWidth:Longint;
  5794. var t  : Integer;
  5795.     tt : Longint;
  5796.     tmp: Integer;
  5797. Begin
  5798.   result:=0;
  5799.   for t:=0 to FSeriesList.Count-1 do
  5800.   With Series[t] do
  5801.   if FXLabels.Count>0 then
  5802.      for tt:=0 to Count-1 do
  5803.          result:=MaxLong(result,MultiLineTextWidth(XLabel[tt],tmp));
  5804. end;
  5805.  
  5806. Function TCustomAxisPanel.MaxMarkWidth:Longint;
  5807. var t : Integer;
  5808. Begin
  5809.   result:=0;
  5810.   for t:=0 to FSeriesList.Count-1 do
  5811.   With Series[t] do if FActive then result:=MaxLong(result,MaxMarkWidth);
  5812. end;
  5813.  
  5814. Function TCustomAxisPanel.GetSeries(Index:Longint):TChartSeries;
  5815. Begin
  5816.   result:=FSeriesList.Items[Index];
  5817. end;
  5818.  
  5819. Procedure TCustomAxisPanel.CalcSize3DWalls;
  5820. var tmpNumSeries : Integer;
  5821.     tmp          : Double;
  5822. Begin
  5823.   if View3D then
  5824.   Begin
  5825.     tmp:=0.001*Chart3DPercent;
  5826.     if not View3DOptions.Orthogonal then tmp:=tmp*2;
  5827.     FSeriesWidth3D :=Round(tmp*ChartWidth);
  5828.     FSeriesHeight3D:=FSeriesWidth3D;
  5829. {ratio:   FSeriesHeight3D:=Round(tmp*ChartHeight);  *10/100.0 % }
  5830.     if ApplyZOrder then tmpNumSeries:=MaxLong(1,MaxZOrder+1)
  5831.                    else tmpNumSeries:=1;
  5832.     Height3D:=FSeriesHeight3D * tmpNumSeries;
  5833.     Width3D :=FSeriesWidth3D  * tmpNumSeries;
  5834.   end
  5835.   else
  5836.   begin
  5837.     FSeriesWidth3D :=0;
  5838.     FSeriesHeight3D:=0;
  5839.     Width3D        :=0;
  5840.     Height3D       :=0;
  5841.   end;
  5842. end;
  5843.  
  5844. Procedure TCustomAxisPanel.InternalDraw(Const UserRectangle:TRect);
  5845.  
  5846.   Procedure DrawSeries(TheSeries:TChartSeries);
  5847.   Var ActiveRegion : Boolean;
  5848.  
  5849.     Procedure ClipRegionCreate;
  5850.     Begin
  5851.       if CanClip then
  5852.       begin
  5853.         Canvas.ClipCube(ChartRect,0,Width3D);
  5854.         ActiveRegion:=True;
  5855.       end;
  5856.     end;
  5857.  
  5858.     Procedure ClipRegionDone;
  5859.     Begin
  5860.       if ActiveRegion then
  5861.       begin
  5862.         Canvas.UnClipRectangle;
  5863.         ActiveRegion:=False;
  5864.       end;
  5865.     end;
  5866.  
  5867.     Procedure DrawAllSeriesValue(ValueIndex:Longint);
  5868.  
  5869.       Procedure TryDrawSeries(ASeries:TChartSeries);
  5870.       begin
  5871.         With ASeries do
  5872.          if FActive and (ZOrder=TheSeries.ZOrder) and (ValueIndex<Count) then
  5873.             DrawValue(ValueIndex)
  5874.       end;
  5875.  
  5876.     var t    : Integer;
  5877.         tmp1 : Integer;
  5878.         tmp2 : Integer;
  5879.     Begin
  5880.       tmp1:=FSeriesList.IndexOf(TheSeries);
  5881.       tmp2:=FSeriesList.Count-1;
  5882.       if ValueIndex<TheSeries.Count then
  5883.       begin
  5884.         if TheSeries.DrawSeriesForward(ValueIndex) then
  5885.            for t:=tmp1 to tmp2 do TryDrawSeries(Series[t])
  5886.         else
  5887.            for t:=tmp2 downto tmp1 do TryDrawSeries(Series[t])
  5888.       end
  5889.       else
  5890.            for t:=tmp1 to tmp2 do TryDrawSeries(Series[t])
  5891.     end;
  5892.  
  5893.     Procedure DrawMarksSeries(ASeries:TChartSeries);
  5894.     begin
  5895.       With ASeries,FMarks do
  5896.       if FVisible then
  5897.       Begin
  5898.         if FClip then ClipRegionCreate;
  5899.         DrawMarks;
  5900.         if FClip then ClipRegionDone;
  5901.       end;
  5902.     end;
  5903.  
  5904.   Var t        : Longint;
  5905.       tmpFirst : Longint;
  5906.       tmpLast  : Longint;
  5907.   Begin
  5908.     ActiveRegion:=False;  { <-- VERY IMPORTANT !!!! }
  5909.     With TheSeries do
  5910.     if View3D and MoreSameZOrder then
  5911.     Begin
  5912.       if FirstInZOrder then
  5913.       Begin
  5914.         ActiveRegion:=False;
  5915.         tmpFirst:=-1;
  5916.         tmpLast :=-1;
  5917.         for t:=SeriesList.IndexOf(TheSeries) to FSeriesList.Count-1 do
  5918.         With Series[t] do
  5919.         if Active and (ZOrder=TheSeries.ZOrder) then
  5920.         Begin
  5921.           CalcFirstLastVisibleIndex;
  5922.           if FFirstVisibleIndex<>-1 then
  5923.           Begin
  5924.             if tmpFirst=-1 then tmpFirst:=FFirstVisibleIndex
  5925.                            else tmpFirst:=MaxLong(tmpFirst,FFirstVisibleIndex);
  5926.             if tmpLast=-1 then tmpLast:=FLastVisibleIndex
  5927.                           else tmpLast:=MaxLong(tmpLast,FLastVisibleIndex);
  5928.             DoBeforeDrawValues;
  5929.             if FClipPoints and (not ActiveRegion) then ClipRegionCreate;
  5930.           end;
  5931.         end;
  5932.         { values }
  5933.         if tmpFirst<>-1 then
  5934.           if DrawValuesForward then
  5935.              for t:=tmpFirst to tmpLast do DrawAllSeriesValue(t)
  5936.           else
  5937.              for t:=tmpLast downto tmpFirst do DrawAllSeriesValue(t);
  5938.  
  5939.         { Region }
  5940.         ClipRegionDone;
  5941.  
  5942.         { Marks and DoAfterDrawValues }
  5943.         for t:=SeriesList.IndexOf(TheSeries) to FSeriesList.Count-1 do
  5944.         With Series[t] do
  5945.         if Active and (ZOrder=TheSeries.ZOrder) and (FFirstVisibleIndex<>-1) then
  5946.         begin
  5947.           DrawMarksSeries(Series[t]);
  5948.           DoAfterDrawValues;
  5949.         end;
  5950.       end;
  5951.     end
  5952.     else
  5953.     Begin
  5954.       CalcFirstLastVisibleIndex;
  5955.       if FFirstVisibleIndex<>-1 then
  5956.       Begin
  5957.         DoBeforeDrawValues;
  5958.         if FClipPoints then ClipRegionCreate;
  5959.         DrawAllValues;
  5960.         if FClipPoints then ClipRegionDone;
  5961.         DrawMarksSeries(TheSeries);
  5962.         DoAfterDrawValues;
  5963.       end;
  5964.     End;
  5965.   end;
  5966.  
  5967.   Procedure SetSeriesZOrder;
  5968.   Var tmpSeries : Integer;
  5969.   begin
  5970.     FMaxZOrder:=0;
  5971.     if ApplyZOrder then
  5972.        if View3D then
  5973.        Begin
  5974.          FMaxZOrder:=-1;
  5975.          for tmpSeries:=0 to FSeriesList.Count-1 do
  5976.              With Series[tmpSeries] do if FActive then CalcZOrder;
  5977.        end;
  5978.     { invert Z Orders }
  5979.     for tmpSeries:=0 to FSeriesList.Count-1 do
  5980.     With Series[tmpSeries] do
  5981.     if FActive then
  5982.        if View3D and ApplyZOrder then IZOrder:=MaxZOrder-ZOrder
  5983.                                  else IZOrder:=0;
  5984.   end;
  5985.  
  5986.   Procedure SetSeriesZPositions;
  5987.   Var tmpSeries : Integer;
  5988.   begin
  5989.     for tmpSeries:=0 to FSeriesList.Count-1 do
  5990.     With Series[tmpSeries] do
  5991.     if Active then
  5992.     begin
  5993.       StartZ :=IZOrder*SeriesWidth3D;
  5994.       EndZ   :=StartZ+SeriesWidth3D;
  5995.       MiddleZ:=(StartZ+EndZ) div 2;
  5996.       FMarks.ZPosition:=MiddleZ;
  5997.     end;
  5998.   end;
  5999.  
  6000.   Procedure DrawAllAxis;
  6001.   var t       : Integer;
  6002.       tmpAxis : TChartAxis;
  6003.   Begin
  6004.     if Assigned(FOnBeforeDrawAxes) then FOnBeforeDrawAxes(Self);
  6005.     With FAxes do
  6006.     for t:=0 to Count-1 do
  6007.     begin
  6008.       tmpAxis:=TChartAxis(Items[t]);
  6009.       if IsAxisVisible(tmpAxis) then tmpAxis.Draw(True);
  6010.     end;
  6011.   end;
  6012.  
  6013. Var tmpSeries : Integer;
  6014. Begin
  6015.   PanelPaint(UserRectangle);
  6016.   for tmpSeries:=0 to FSeriesList.Count-1 do
  6017.   With Series[tmpSeries] do if Active then DoBeforeDrawChart;
  6018.  
  6019.   DrawTitlesAndLegend;
  6020.  
  6021.   SetSeriesZOrder;
  6022.   CalcAxisRect;
  6023.   SetSeriesZPositions;
  6024.   CalcSeriesRect;
  6025.  
  6026.   InternalCanvas.Projection(Width3D,ChartBounds,ChartRect);
  6027.  
  6028.   DrawWalls;
  6029.   if FAxisVisible and TeeDrawAxisBeforeSeries then DrawAllAxis;
  6030.  
  6031.   if Assigned(FOnBeforeDrawSeries) then FOnBeforeDrawSeries(Self);
  6032.  
  6033.   for tmpSeries:=0 to FSeriesList.Count-1 do
  6034.   if Series[tmpSeries].Active then DrawSeries(Series[tmpSeries]);
  6035.  
  6036.   if FAxisVisible and (not TeeDrawAxisBeforeSeries) then DrawAllAxis;
  6037.  
  6038.   if IZoom.Active then DrawZoomRectangle;
  6039.   Canvas.ResetState;
  6040.   if Assigned(FOnAfterDraw) then FOnAfterDraw(Self);
  6041. end;
  6042.  
  6043. procedure TCustomAxisPanel.SetView3DWalls(Value:Boolean);
  6044. Begin
  6045.   SetBooleanProperty(FView3DWalls,Value);
  6046. end;
  6047.  
  6048. {$IFDEF D1}
  6049. Procedure TCustomAxisPanel.WriteComponents(Writer:TWriter);
  6050. var t : Integer;
  6051. begin
  6052.   for t:=0 to FSeriesList.Count-1 do Writer.WriteComponent(FSeriesList[t]);
  6053.   inherited WriteComponents(Writer);
  6054. end;
  6055. {$ELSE}
  6056. Procedure TCustomAxisPanel.GetChildren(Proc:TGetChildProc{$IFDEF D3}; Root:TComponent{$ENDIF});
  6057. var t : Integer;
  6058. begin
  6059.   inherited GetChildren(Proc{$IFDEF D3},Root{$ENDIF});
  6060.   for t := 0 to FSeriesList.Count-1 do Proc(FSeriesList[t]);
  6061. end;
  6062. {$ENDIF}
  6063.  
  6064. procedure TCustomAxisPanel.RemovedDataSource( ASeries: TChartSeries;
  6065.                                               AComponent: TComponent );
  6066. begin
  6067. end;
  6068.  
  6069. procedure TCustomAxisPanel.SetClipPoints(Value:Boolean);
  6070. Begin
  6071.   SetBooleanProperty(FClipPoints,Value);
  6072. end;
  6073.  
  6074. procedure TCustomAxisPanel.SetLeftAxis(Value:TChartAxis);
  6075. begin
  6076.   FLeftAxis.Assign(Value);
  6077. end;
  6078.  
  6079. procedure TCustomAxisPanel.SetDepthAxis(Value:TChartDepthAxis);
  6080. begin
  6081.   FDepthAxis.Assign(Value);
  6082. end;
  6083.  
  6084. procedure TCustomAxisPanel.SetRightAxis(Value:TChartAxis);
  6085. begin
  6086.   FRightAxis.Assign(Value);
  6087. end;
  6088.  
  6089. procedure TCustomAxisPanel.SetTopAxis(Value:TChartAxis);
  6090. begin
  6091.   FTopAxis.Assign(Value);
  6092. end;
  6093.  
  6094. procedure TCustomAxisPanel.SetBottomAxis(Value:TChartAxis);
  6095. begin
  6096.   FBottomAxis.Assign(Value);
  6097. end;
  6098.  
  6099. Procedure TCustomAxisPanel.RemoveSeries(ASeries:TChartSeries);
  6100. var t : Integer;
  6101. Begin
  6102.   t:=FSeriesList.IndexOf(ASeries);
  6103.   if t<>-1 then
  6104.   begin
  6105.     With ASeries do
  6106.     Begin
  6107.       RemoveAllLinkedSeries;
  6108.       FParent:=nil;
  6109.       { this is necesary... }
  6110.       if Self.Cursor=Cursor then Self.Cursor:=OriginalCursor;
  6111.     end;
  6112.     FSeriesList.Delete(t);
  6113. {    if not (csDesigning in ComponentState) then  <--hotfix for AV bug in D3 }
  6114.        Invalidate;
  6115.   end;
  6116. end;
  6117.  
  6118. Function TCustomAxisPanel.GetAxisSeries(Axis:TCustomChartAxis):TChartSeries;
  6119. Var t : Integer;
  6120. Begin
  6121.   for t:=0 to FSeriesList.Count-1 do
  6122.   begin
  6123.     result:=Series[t];
  6124.     With result do
  6125.     if FActive and AssociatedToAxis(Axis) then Exit;
  6126.   end;
  6127.   result:=nil;
  6128. end;
  6129.  
  6130. Function TCustomAxisPanel.FormattedValueLegend(ASeries:TChartSeries; ValueIndex:Longint):String;
  6131. begin { virtual, overrided at TChart }
  6132. end;
  6133.  
  6134. Function TCustomAxisPanel.GetFreeSeriesColor(CheckBackground:Boolean):TColor;
  6135. var t : Integer;
  6136. Begin
  6137.   t:=0;
  6138.   Repeat
  6139.     result:=GetDefaultColor(t);
  6140.     inc(t);
  6141.   Until (t>MaxDefaultColors) or IsFreeSeriesColor(result,CheckBackground);
  6142. end;
  6143.  
  6144. Procedure TCustomAxisPanel.AddSeries(ASeries:TChartSeries);
  6145. begin
  6146.   ASeries.ParentChart:=Self;
  6147. end;
  6148.  
  6149. Procedure TCustomAxisPanel.InternalAddSeries(ASeries:TChartSeries);
  6150. Begin
  6151.   if FSeriesList.IndexOf(ASeries)=-1 then
  6152.   begin
  6153.     with ASeries do
  6154.     begin
  6155.       if FColor=clTeeColor then SeriesColor:=GetFreeSeriesColor(True);
  6156.       FParent:=Self;
  6157.       if (csDesigning in ComponentState) and (ASeries.FunctionType=nil) then
  6158.          FillSampleValues(NumSampleValues)
  6159.       else
  6160.          CheckDatasource;
  6161.     end;
  6162.     FSeriesList.Add(ASeries);
  6163.     Invalidate;
  6164.   end;
  6165. end;
  6166.  
  6167. Function TCustomAxisPanel.GetMaxValuesCount:Longint;
  6168. var t         : Integer;
  6169.     FirstTime : Boolean;
  6170. Begin
  6171.   result:=0;
  6172.   FirstTime:=True;
  6173.   for t:=0 to FSeriesList.Count-1 do
  6174.   with Series[t] do
  6175.   if FActive and ( FirstTime or (Count>result) ) then
  6176.   begin
  6177.     result:=Count;
  6178.     FirstTime:=False;
  6179.   end;
  6180. end;
  6181.  
  6182. Procedure TCustomAxisPanel.SetAxisVisible(Value:Boolean);
  6183. Begin
  6184.   SetBooleanProperty(FAxisVisible,Value);
  6185. end;
  6186.  
  6187. Procedure TCustomAxisPanel.CheckOtherSeries(Dest,Source:TChartSeries);
  6188. var t:Longint;
  6189. Begin
  6190.   if Assigned(Source) then
  6191.   if Source.DataSource=Dest then
  6192.      Raise ChartException.Create(TeeMsg_CircularSeries)
  6193.   else
  6194.      if Source.DataSource is TChartSeries then
  6195.      for t:=0 to Source.FDataSources.Count-1 do
  6196.         CheckOtherSeries(Dest,TChartSeries(Source.DataSources[t]));
  6197. end;
  6198.  
  6199. Function TCustomAxisPanel.IsValidDataSource(ASeries:TChartSeries; AComponent:TComponent):Boolean;
  6200. Begin
  6201.   result:=(ASeries<>AComponent) and
  6202.           (AComponent is TChartSeries) and
  6203.           ASeries.IsValidSeriesSource(TChartSeries(AComponent));
  6204. end;
  6205.  
  6206. Procedure TCustomAxisPanel.CheckDatasource(ASeries:TChartSeries);
  6207. Begin
  6208.   With ASeries do
  6209.   if not (csLoading in ComponentState) then
  6210.      if (DataSource<>nil) and (DataSource is TChartSeries) then
  6211.         AddValues(TChartSeries(DataSource));
  6212. end;
  6213.  
  6214. Function TCustomAxisPanel.SeriesCount:Longint;
  6215. Begin
  6216.   if FSeriesList=nil then result:=0
  6217.                      else result:=FSeriesList.Count;
  6218. end;
  6219.  
  6220. Procedure TCustomAxisPanel.Assign(Source:TPersistent);
  6221. begin
  6222.   if Source is TCustomAxisPanel then
  6223.   With TCustomAxisPanel(Source) do
  6224.   begin
  6225.     Self.FAxisVisible      := FAxisVisible;
  6226.     Self.FBottomAxis.Assign(FBottomAxis);
  6227.     Self.FClipPoints       := FClipPoints;
  6228.     Self.FLeftAxis.Assign(FLeftAxis);
  6229.     Self.FDepthAxis.Assign(FDepthAxis);
  6230.     Self.FMaxPointsPerPage := FMaxPointsPerPage;
  6231.     Self.FPage:=FPage;
  6232.     Self.FRightAxis.Assign(FRightAxis);
  6233.     Self.FScaleLastPage    := FScaleLastPage;
  6234.     Self.FTopAxis.Assign(FTopAxis);
  6235.     Self.FView3DWalls      := FView3DWalls;
  6236.   end;
  6237.   inherited Assign(Source);
  6238. end;
  6239.  
  6240. initialization
  6241.   RegisterClasses([ TChartAxis,TChartDepthAxis,TSeriesMarks,TChartAxisTitle ]);
  6242. end.
  6243.